JavaScript - examples of reduce() function - javascript

I'm looking at this example of use of reduce() function.
function add(runningTotal, currentValue) {
return runningTotal + currentValue;
}
var nums = [1,2,3,4,5,6,7,8,9,10];
var sum = nums.reduce(add);
print(sum); // displays 55
Could you give show me some other examples of using reduce() - I'm not sure I fully follow how it works.
Thank you

What reduces does is take an initialValue, a function with 2 essential parameters (can take more) and a list of values. If no initialValue is provided then it's assumed it's the first element of the list. The function is supposed to do something with the previousValue usually used as an accumulator and the nextValue.
So, assume you have a list of values: [1, 2, 3, 4, 5] and the function is supposed to add the 2 parameters and an initialValue of 0.
First step:
0 + 1 = 1
2
3
4
5
Second step:
1 + 2 = 3
3
4
5
Third Step:
3 + 3 = 6
4
5
Fourth Step:
6 + 4 = 10
5
Fifth Step:
10 + 5 = 15 //Final value
As you can see, the input went from a list to a single value, hence the name reduce. In your example, there's no initialValue (that's the second argument), so it's as if started on the second step.

You can set second argument for reduce
function add(runningTotal, currentValue) {
return runningTotal + currentValue;
}
var someInitValue = 10
var nums = [1,2,3,4,5,6,7,8,9,10];
var sum = nums.reduce(add, someInitValue);
console.log(sum); // displays 65

reduce() works by iterating over an array and calling a reductor function (this function is the first argument passed to reduce(). This function has four arguments:
previousValue, which is sort of a 'running total'. this is initially undefined, unless you provide a seed value as the second argument to reduce().
currentValue which is an object in your array
index of the current value in your array
array, the array itself
when your reductor function is called, its return value becomes the new previousValue argument for next time the reductor function is called. that's the magic. after the reductor function is called and given the very last object in the array, its return value will be the return value of reduce().
honestly, a lot of the examples you'll see (like using reduce() to sum up a bunch of integers) are pretty easy to do with a for() loop. its real value is when you're doing functional programming.

You can also use reduce to do things like generate some kind of stream cipher.
var plaintext = "thisisaplaintext";
var chars = plaintext.split('');
var result = '';
function encrypt(runningTotal, currentValue){
var newVal = ((runningTotal + (""+runningTotal).charCodeAt()-32) % 94)+32
result = result + String.fromCharCode(newVal)
return newVal;
}
chars.reduce(encrypt, 15 /*any arbitrary starting value*/);
console.log(result);
Basically, anything that can be made with a combination of independent calculations or anything that requires some rolling total. It's nothing that you couldn't already do with a for loop, but it looks cleaner.

Related

Recursion better understanding

https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/use-recursion-to-create-a-countdown
We have defined a function called countdown with one parameter (n). The function should use recursion to return an array containing the integers n through 1 based on the n parameter. If the function is called with a number less than 1, the function should return an empty array. For example, calling this function with n = 5 should return the array [5, 4, 3, 2, 1]. Your function must use recursion by calling itself and must not use loops of any kind.
// Only change code below this line
function countdown(n){
if (n<1)
return [];
else{
const numbArray = countdown(n-1);
numbArray.push(n)
return numbArray;
}
}
console.log(countdown(5))
// Only change code above this line
comes out like [1 2 3 4 5] instead of [5 4 3 2 1]
I've been breaking my mind forever then I have completed it with the unshift method but felt like it wanted to me use push even though that sends data to the end of the stack
function countdown(max, currentN) {
if (currentN > max)
return [];
else if (currentN <= max) {
const numbArray = countdown(max, currentN + 1);
numbArray.push(currentN)
return numbArray;
}
}
console.log(countdown(5, 1))
// Only change code above this line
basically it just counts up to the end value given at start
else {
const arr = []
arr.push(n)
return arr.concat(countdown(n-1))
}
you can use this code replace, y question reason is y not understand recursion, try to break the point and watch the function execution step by step in the browser or vscode

Why does an object exist in two sum solution? [duplicate]

Im just wondering who can explain the algorithm of this solution step by step. I dont know how hashmap works. Can you also give a basic examples using a hashmap for me to understand this algorithm. Thank you!
var twoSum = function(nums, target) {
let hash = {};
for(let i = 0; i < nums.length; i++) {
const n = nums[i];
if(hash[target - n] !== undefined) {
return [hash[target - n], i];
}
hash[n] = i;
}
return [];
}
Your code takes an array of numbers and a target number/sum. It then returns the indexes in the array for two numbers which add up to the target number/sum.
Consider an array of numbers such as [1, 2, 3] and a target of 5. Your task is to find the two numbers in this array which add to 5. One way you can approach this problem is by looping over each number in your array and asking yourself "Is there a number (which I have already seen in my array) which I can add to the current number to get my target sum?".
Well, if we loop over the example array of [1, 2, 3] we first start at index 0 with the number 1. Currently, there are no numbers which we have already seen that we can add with 1 to get our target of 5 as we haven't looped over any numbers yet.
So, so far, we have met the number 1, which was at index 0. This is stored in the hashmap (ie object) as {'1': 0}. Where the key is the number and the value (0) is the index it was seen at. The purpose of the object is to store the numbers we have seen and the indexes they appear at.
Next, the loop continues to index 1, with the current number being 2. We can now ask ourselves the question: Is there a number which I have already seen in my array that I can add to my current number of 2 to get the target sum of 5. The amount needed to add to the current number to get to the target can be obtained by doing target-currentNumber. In this case, we are currently on 2, so we need to add 3 to get to our target sum of 5. Using the hashmap/object, we can check if we have already seen the number 3. To do this, we can try and access the object 3 key by doing obj[target-currentNumber]. Currently, our object only has the key of '1', so when we try and access the 3 key you'll get undefined. This means we haven't seen the number 3 yet, so, as of now, there isn't anything we can add to 2 to get our target sum.
So now our object/hashmap looks like {'1': 0, '2': 1}, as we have seen the number 1 which was at index 0, and we have seen the number 2 which was at index 1.
Finally, we reach the last number in your array which is at index 2. Index 2 of the array holds the number 3. Now again, we ask ourselves the question: Is there a number we have already seen which we can add to 3 (our current number) to get the target sum?. The number we need to add to 3 to get our target number of 5 is 2 (obtained by doing target-currentNumber). We can now check our object to see if we have already seen a number 2 in the array. To do so we can use obj[target-currentNumber] to get the value stored at the key 2, which stores the index of 1. This means that the number 2 does exist in the array, and so we can add it to 3 to reach our target. Since the value was in the object, we can now return our findings. That being the index of where the seen number occurred, and the index of the current number.
In general, the object is used to keep track of all the previously seen numbers in your array and keep a value of the index at which the number was seen at.
Here is an example of running your code. It returns [1, 2], as the numbers at indexes 1 and 2 can be added together to give the target sum of 5:
const twoSum = function(nums, target) {
const hash = {}; // Stores seen numbers: {seenNumber: indexItOccurred}
for (let i = 0; i < nums.length; i++) { // loop through all numbers
const n = nums[i]; // grab the current number `n`.
if (hash[target - n] !== undefined) { // check if the number we need to add to `n` to reach our target has been seen:
return [hash[target - n], i]; // grab the index of the seen number, and the index of the current number
}
hash[n] = i; // update our hash to include the. number we just saw along with its index.
}
return []; // If no numbers add up to equal the `target`, we can return an empty array
}
console.log(twoSum([1, 2, 3], 5)); // [1, 2]
A solution like this might seem over-engineered. You might be wondering why you can't just look at one number in the array, and then look at all the other numbers and see if you come across a number that adds up to equal the target. A solution like that would work perfectly fine, however, it's not very efficient. If you had N numbers in your array, in the worst case (where no two numbers add up to equal your target) you would need to loop through all of these N numbers - that means you would do N iterations. However, for each iteration where you look at a singular number, you would then need to look at each other number using a inner loop. This would mean that for each iteration of your outer loop you would do N iterations of your inner loop. This would result in you doing N*N or N2 work (O(N2) work). Unlike this approach, the solution described in the first half of this answer only needs to do N iterations over the entire array. Using the object, we can find whether or not a number is in the object in constant (O(1)) time, which means that the total work for the above algorithm is only O(N).
For further information about how objects work, you can read about bracket notation and other property accessor methods here.
You may want to check out this method, it worked so well for me and I have written a lot of comments on it to help even a beginner understand better.
let nums = [2, 7, 11, 15];
let target = 9;
function twoSums(arr, t){
let num1;
//create the variable for the first number
let num2;
//create the variable for the second number
let index1;
//create the variable for the index of the first number
let index2;
//create the variable for the index of the second number
for(let i = 0; i < arr.length; i++){
//make a for loop to loop through the array elements
num1 = arr[i];
//assign the array iteration, i, value to the num1 variable
//eg: num1 = arr[0] which is 2
num2 = t - num1;
//get the difference between the target and the number in num1.
//eg: t(9) - num1(2) = 7;
if(arr.includes(num2)){
//check to see if the num2 number, 7, is contained in the array;
index1 = arr.indexOf(num2);
//if yes get the index of the num2 value, 7, from the array,
// eg: the index of 7 in the array is 1;
index2 = arr.indexOf(num1)
//get the index of the num1 value, which is 2, theindex of 2 in the array is 0;
}
}
return(`[${index1}, ${index2}]`);
//return the indexes in block parenthesis. You may choose to create an array and push the values into it, but consider space complexities.
}
console.log(twoSums(nums, target));
//call the function. Remeber we already declared the values at the top already.
//In my opinion, this method is best, it considers both time complexity and space complexityat its lowest value.
//Time complexity: 0(n)
function twoSum(numbers, target) {
for (let i = 0; i < numbers.length; i++) {
for (let j = i + 1; j < numbers.length; j++) {
if (numbers[i] + numbers[j] === target) {
return [numbers.indexOf(numbers[i]), numbers.lastIndexOf(numbers[j])];
}
}
}
}

How would you find the values in an array that equal the sum a specified number?

I'm working on creating a basic function that takes in 2 parameters -- array and num.
In the array are a list of numbers and the output could essentially generate 3 results:
0 with no two numbers that equal the sum equal to num.
1 variation of two numbers that is equal to the sum that is num
Multiple variations of 2 numbers that equal the sum that is num
I've been working with filter and reduce but haven't been able to produce the desired output.
Let's say I have a nums array of [3,6,9,18] and have a specified num value of 15.
var findNumSum = function(nums, num) {
function val(a, b) {
a + b === num;
var es = [a, b]
return es;
}
var result1 = nums.filter(val); // [3,6,9,18]
var result2 = nums.reduce(val); // [[6, 9], 18]] -- I've been able to isolate the num values but wasn't the result I was expecting. I'm still pretty fresh at this.
};
Let's assume you want to find sums for the number 6. Check the first number of the array, let it be 2. You now want to know if there's a 4 in you array, so you check that. Do this process for all the numbers in the array and remove duplicates.
Maybe this could help ?
Here is a little snippets along the lines of the previous suggestions:
const arr=[...Array(25)].map((_,v,)=>v), // create an array with 25 numbers
findsum=(ar,sum)=>
ar.reduce((a,c,i)=>
(c>sum || ar.slice(i+1).forEach(v=>
c+v-sum || a.push([c,v])),a)
,[] );
console.log(findsum(arr,27)) // find all possible pairs that add up to 27
Maybe it is helpful to you?
Only if the first condition c>sum is false the following ar.slice(i+1).forEach(...) will be executed. inside the forEach()-callback function the a.push([c,v]) will only be performed c+v-sum is "falsy" i. e. ==0.

How to find the count of repeated numbers in an given array and return the output as an object

I have been asked with this question in one of my recent interviews.
For a given array, say, Arr[2,2,4,3,4,2,3,2,4]
write a javascript function to return an object with the count of each number in the above array, like
countArr={2:4,3:2,4:3}
After a lot of google I have ended up with the below code which is returning the correct data.
var uniqueCount = [2, 2, 4, 3, 4, 2, 3, 2];
var count = {};
uniqueCount.forEach(function(i) {
count[i] = (count[i] || 0) + 1;
});
console.log(count);
As I said this works fine! Output: {2: 4, 3: 2, 4: 2}
Well, a code without proper understanding of whats happening in back ground means nothing for a developer :)
Can anyone please help me out to understand how this actually work?
The main work of creating an object with each of the unique array element's count
is happening in the following block:
uniqueCount.forEach(function(i) {
count[i] = (count[i] || 0) + 1;
});
Here we are iterating over each of the elements in the array like we do in a 'for loop'. I hope you are familiar with the working of a 'for loop'. Then, we are passing each element of the array in a function.
count[i] = (count[i] || 0) +1;
can be written as:
if(count[i]) {
count[i] = count[i] + 1;
} else {
count[i] = 1;
}
Hope that helps you to understand the code.
Ok, it's actually simple. Let's go step by step.
var count = {};
Declares a JS object. It's basically a key-value store. You can access the value of a key by writing count[key]. Then store or retrieve the value.
Consider this simple example:
var count = {}
count['ok'] = 3
console.log(count)
It outputs { ok: 3 }
Now replace 'ok' with a number, and you get the structure of the rest of the code : keys are added to the object for each number found in the array, or are incremented when they exists.
Let's continue with the code.
uniqueCount.forEach(function(i) {
// code here is called for each entry in the uniqueCount array, i being the current value.
});
And finally, the magic happens here:
count[i] = (count[i] || 0) + 1;
From left to right, it reads: assign to the i property of the count object a value that is it's current value or 0 if there is none, then add 1. So if the i number was already seen it takes the previous value and adds 1; if it wasn't seen, it takes 0 and adds one.
So when you console.log(count) you get the values for all of those properties.
The code uses an object as a map from number values to integer counts of their frequency.
1. var uniqueCount = [2, 2, 4, 3, 4, 2, 3, 2];
2. var count = {};
3. uniqueCount.forEach(function(i) {
4. count[i] = (count[i] || 0) + 1;
5. });
6. console.log(count);
Line 1: Declare variable uniqueCount and assign to it a new array of numbers.
Line 2: Declare variable count and assign to it a new, empty object.
Line 3: Run an anonymous function once for each number in uniqueCount.
Line 4: Assign to a property on count, named with the current number in the array: one plus the existing value of the property, or if the property does not already exist, zero.
Line 6: Print the final state of count.
The code would be clearer if the variable i in the anonymous function was named n (or something) because i (yes, I know it means "integer" here) usually means "index", and here, it is not the index.
Note that in JavaScript simply assigning a value to a property on an object will create that property if it does not already exist.
I assume there is only one line that confused you:
count[i] = (count[i] || 0) + 1; means
If there is already a count for digit i set count[i] to that value, otherwise set it to 0 (initialise it) then add 1 to whatever is in count[i] now
Can be rewritten like this to make it more understandable - note I changed the variable, array and object names
var array = [2, 2, 4, 3, 4, 2, 3, 2];
var uniqueCount = {};
array.forEach(function(digit) {
if (uniqueCount[digit]) uniqueCount[digit]++; // if counter for the digit exist, add 1
else uniqueCount[digit] = 1; // else initialise it to 1
});
console.log(uniqueCount);

How to generate proportional numbers between 0 and 1 with an array?

I want to generate a proportional array of numbers between 0 and 1 with an array of sales that has different size values.
For example if I have the values [1, 80, 2000] it would be ok an array like [0.1, 0.4, 1].
a modern functional approach:
var r=[1, 80, 2000] ;
r.map(function(a){
return a/this;
}, Math.max.apply(0,r) );
//==[0.0005,0.04,1]
i think math was off in OP...
edit: details on what's going on here:
The problem is broken down into two steps.
find the largest number in the Array
compute each Array item as a portion of the largest item
For the first step, JS provides the Math.max function. To use an argument-based function with an array, the function's apply() method is used, and 0 is passed as "this", but it's not really used; it just needs to be something.
The second step compares each item to the number found in step #1, using the Array.map method to iterate the Array and return the result of an operation upon each item in the Array. Since Array.map() can accept an optional "this" argument, the largest number from step #1 is passed as "this" to avoid a performance-robbing function closure.
though it is not clear, what should be the relationship between original array and the generated array. Am assuming you want to create what fraction the item is of the total sum (proportion):
try this:
function generateProportion(arr){
//find out the total sum..
var total = 0;
for(var k=0;k <arr.length;k++)
total += arr[k];
//push the ratios into the new array with double precison..
var newArr = new Array();
for(var i=0;i< arr.length; i++)
newArr.push((arr[i]/total).toFixed(2));
console.log(newArr);
return newArr;
}
and call it like this:
var a = [1, 80, 2000];
generateProportion(a);
see this fiddle

Categories

Resources