What does it mean to use the reduce method in Javascript? - javascript

I'm doing the Free Code Camp series of tutorials and I got the answer right but don't understand a few things ...
Exercise:
Use the reduce method to sum all the values in array and assign it to singleVal.
singleVal should be equal to the sum of all items in the array variable.
You should have made use of the reduce method.
var array = [4,5,6,7,8];
var singleVal = 0;
singleVal = array.reduce(function(previousVal,currentVal){
return previousVal + currentVal;
},0);
I got the answer right by following the example basically.. but I can't understand why there is a comma zero at the end - like what is the point of it?

The comma zero at the end denotes the initial value.
The syntax of reduce is array.reduce(function(total, currentValue, currentIndex, arr), initialValue). Mentioning initialValue is Optional. A value to be passed to the function as the initial value.
Consider the following example:
var array = [4,5,6,7,8];
var singleVal = 0;
//reduce function takes 5 as the initial value then sums up the values of
//the array.
singleVal = array.reduce(function(previousVal,currentVal){
return previousVal + currentVal;
},5); //5 is passed to the function as the initial value.
console.log(singleVal) //35

Related

Assign a array of indexes as an object value

I have an assignment which i need to sole but i am really stuck and can't make a progress. The assignment consist in an array of elements like this
const appleHolderLine = ['Rome', 'Ambrosia', 'Rome', 'RedDelicious', 'Akane','RedDelicious', 'SweeTango', 'RedDelicious', 'RedDelicious', 'Opal', 'Winesap', 'RedDelicious', 'Empire', 'RedDelicious', 'Liberty'];
Firstly it is needed to declare a variable lineCount which count for every element of the array and a reference to an object called appleMap.
Than the challenge consist in looping through the array and the elements of the array would be the object keys with no duplicates and the values would be an array of idexes of the specific element place of the array. To give an example how it should look like:
Example:
const appleHolderLine = ['GreenApples', 'RedDelicious','OrangeApples', 'PurpleApples', 'RedDelicious']
console.log (lineCount, appleMap)
Should Log:
5, {'GreenApples':[0], 'RedDelicious': [1,4], 'OrangeApples':[2], 'PurpleApples': [3]}
My progress so far
var lineCount = 0;
var appleMap = {};
for (let i = 0; i < appleHolderLine.length; i++){
lineCount++;
// if element in the array exist in the array
appleMap[appleHolderLine[i]] = [i];
}
Could you give me a hint of how to solve this, i am really stuck.
Basically you can create an empty array the first time and keep pushing like below
var lineCount = 0;
var appleMap = {};
for (let i = 0; i < appleHolderLine.length; i++){
lineCount++;
if(!appleMap[appleHolderLine[i]])
appleMap[appleHolderLine[i]] = []
appleMap[appleHolderLine[i]].push(i);
}
You could use Array.prototype.reduce which is a more advanced construct javascript provides. Please refer to answer by CodeManiac below for the same.
The above answer is to clarify the basic idea and hint on how you could think
Also, lineCount can be obtained by using appleHolderLine.length directly.
You don't need an extra variable ( Line count ) here, simply loop over the value use, use the index to access value, check if there's nothing present for that key then just initialize it with empty array, push index to the key in each iteration
const appleHolderLine = ['GreenApples', 'RedDelicious','OrangeApples', 'PurpleApples', 'RedDelicious']
var appleMap = {};
for (let i = 0; i < appleHolderLine.length; i++){
if(!appleMap[appleHolderLine[i]]){
appleMap[appleHolderLine[i]] = []
}
appleMap[appleHolderLine[i]].push(i);
}
console.log(appleMap)
You can simply use reduce
const appleHolderLine = ['GreenApples', 'RedDelicious','OrangeApples', 'PurpleApples', 'RedDelicious']
let final = appleHolderLine.reduce((op,inp,i)=>{
op[inp] = op[inp] || []
op[inp].push(i)
return op
},{})
console.log(final)
Line count is simply same as length of array, let lineCount = appleHolderLine.length
I suppose, the shortest answer is the functional one.
const appleHolderLine = ['GreenApples', 'RedDelicious','OrangeApples', 'PurpleApples', 'RedDelicious']
result = appleHolderLine.reduce((a,c,i) => { if(a[c]) a[c].push(i); else a[c]=[i]; return a; }, {})
console.log(result)
But I am not sure that you are expected to deliver a functional solution. Still, you might find it useful. The idea is that the reduce method starts with an empty object and iterates through the array. In each iteration, it checks if the current element c is already a field of the accumulator a. If so adds its index i to the specific field, if not, initializes the field with the current element as name and the index as a single-element array as value.

How to sum elements of two multidimensional arrays?

I have 2 multidimensional arrays:
[[230.0], [10.0], [12.0]]
[[50.0], [60.0], [89.0]]
And am trying to sum each element together and keep the same array structure. So it should look like:
[[280.0], [70.0], [101.0]]
I tried this:
var sum = array1.map(function (num, index) {
return num + array2[index];
});
But I get this:
[23050, 1060, 1289]
Any help would be appreciated. Thanks.
The code, you use, takes only a single level, without respecting nested arrays. By taking na array with only one element without an index of the inner array and using an operator, like +, the prototype function toString is invoced and a joined string (the single element as string, without , as separator) is returned and added. The result is a string , not the result of a numerical operation with +.
You could take a recursive approach and check if the value is an array, then call the function again with the nested element.
function sum(a, b) {
return a.map((v, i) => Array.isArray(v) ? sum(v, b[i]) : v + b[i]);
}
console.log(sum([[230], [10], [12]], [[50], [60], [89]]))
Make it like this
var sum = array1.map(function (num, index) {
return parseInt(num) + parseInt(array2[index]);
});
You should have to make parseInt or parseFloat so it can convert string with them
STEPS
Iterate through every number in the array (array length).
Sum the objects of the same index in both of the arrays.
Push the sum into another array for the result. Use parseFloat if the input is string.
(Optional) use .toFixed(1) to set decimal place to have 1 digit.
const arr1 = [[230.0], [10.0], [12.0]]
const arr2 = [[50.0], [60.0], [89.0]]
let sum = []
for (let i = 0; i < arr1.length; i++){ // Assume arr1 and arr2 have the same size
let eachSum = parseFloat(arr1[i]) + parseFloat(arr2[i])
sum.push([eachSum.toFixed(1)])
}
console.log(sum)
You are trying to add two arrays structures inside the map function.
so one solution so you can see what is happening is this...
array1.map((a,i) => a[0] + array2[i][0])
screenshot from the console...
Inside map fn you should:
return parseInt(num) + parseInt(array2[index]);
This is happening because when you are trying to add them, these variable are arrays and not integers. So they are evaluated as strings and concatenated.

Learning While Loops. Can't figure out what I am missing in my code.

Write a function called indexToString. This function should:
1. Take an array as an argument
2. Create and return a new array of all passed array elements as strings
3. Each strings should be formatted like so: “[index] is [element at index]”
This is the error I am getting: returns an array of passed-in array elements as strings with element index specified
expected undefined to deeply equal [ '0 is 1', '1 is 2', '2 is 3' ]
Here is my code:
var indexToString = function(array){
index = 0;
elementAtIndex = 0;
var i = 0;
while(i < array.length){
console.log(index + " is " + elementAtIndex);
i++
}
return array[i];
};
Two Three errors.
Firstly, the while loop will exit when i is no longer less than array.length; the first such number is array.length. This means, at the end of the loop, array[i] is array[array.length], which is just outside the array, thus undefined.
Secondly, you are supposed to return an array of strings, as told by your test failure message; not print them to the console.
EDIT: Thirdly, what Spencer said. :) Use i instead of index, and array[i] instead of elementAtIndex.
You want to start with an empty array outside the loop, and push each string you construct into it; then return that array after the loop.
Or you can do it with "new" JavaScript:
var indexToString = array => array.map((e, i) => `${i} is ${e}`)
You should reflect a bit more on your code, it is quite nonsense so far.
Let's decompose the question to identify what should be done:
Write a function called indexToString. This function should:
Take an array as an argument
Create and return a new array of all passed array elements as strings
Each strings should be formatted like so: “[index] is [element at index]”
So:
you create a function called indexToString which body contains the code, as you did.
In the initialization part before your while, you should create a new empty array that is going to be filled, and declare an integer called index for example initialized at 0 that is going to be used to loop through the original array. (Tip: var new_array = []; to create, and use new_array.push(elem); to append an element)
in your while, you should push at the end of your new array a string built as follow: "["+index+"] is ["+array[index]+"]" AND you should increment your index. You loop while(index < array.length).
At the end, you can return the new array !
Good luck with learning programming!
If the arraylenth is 10, the function will return array[10].This is an array-bound.
When you enter the last loop, the i becomes equal to array.length, so array[i] is undefined after this. But probably this is not what you wanted. you want to return the full array.
var indexToString = function(array){
var new_array = [];
var i = 0;
while(i < array.length){
new_array[i] = i + " is " + array[i];
i++;
}
return new_array;
};
console.log(indexToString([1,2,3]));

How to calculate sum of object keys in array - javascript

Question
I am working with firebase and react native.
I have returned an array from my firebase database that looks like this.
[Object, Object, Object]
Under each object I have returned a single item, "level:4".
So I have three objects containing 4,5,6. How do I sum these together?
Thanks!
You can use Javascript's reduce function. This is basically the same as #epascarello answer but in ES6 syntax.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
const arr = [{level:2},{level:4},{level:5}];
const total = arr.reduce((prev,next) => prev + next.level,0);
console.log(total);
Either a simple loop
var a = [{level:1},{level:2},{level:3},{level:4}],
total = 0;
for (var i=0; i<a.length; i++) {
total += a[i].level;
}
console.log('total', total)
or reduce
var a = [{level:1},{level:2},{level:3},{level:4}]
console.log(a.reduce( function(cnt,o){ return cnt + o.level; }, 0))
Use Array.prototype.forEach() method to iterate over your array and sum your elements.
Let us suppose your array is var foo = [object, object, object]
Each object has this structure, { level : 4 }
Write code like this:
var sum = 0;
foo.forEach(function(obj){
sum += obj.level;
});
sum will store the sum
This code will calculate the sum of an array. First, declare one variable; this variable's name will be sum. sum contains the total's sum. Second, declare a numbers variable of type Array. This variable will contain digits.
Then we start a loop (for) operation, in which we assign to the sum variable the value of (sum= sum+i);.
Then we show in (document.write) the numbers and sum.
var summa = 0 , i ;
var numbers= [1,2,3,4,5];
for(i = 0; i <= numbers.length; i++){
summa=summa+i;
}
document.write(numbers , ": bu reqemlerin cemi " ,"=" , summa);
Have you tried accessing the object in the array and calling the property?
var array = [object, object, object];
var sum = array[0].level + array[1].level + array[2].level;

How to find minimum decimal value in array using javascript

I have array with decimal nos such as
var idArray = ["98.40", "111.46", "144.47", "180.48", "217.49", "284.50", "424.51", "571.52", "1887.53", "1960.54", "1972.55", "2118.56", "2167.57", "2467.58", "2480.59", "2488.60", "2662.61", "2671.62", "2767.63", "2982.64", "3168.65", "3263.66", "3295.67", "3369.68", "3579.69", "3592.70", "3600.71", "3605.72", "3620.73", "3646.74", "3852.75", "3857.76", "4031.77", "4489.78", "4975.79"]
I found the minimum value in the array as below
var result = Math.min.apply(null, idArray );
I got result as 98.4
Is there a way to return actual value in the array as 98.40
You could code your own:
minInArr = function(arr) {
var smallest = arr[0];
for(var i=1; i<arr.length; i++){
if(parseInt(arr[i],10) < smallest){
smallest = arr[i];
}
}
return smallest
}
Made this code based on this one:
Return index of greatest value in an array
There are a couple of methods in addition to those already here (though one is pretty similar to adeneo's). One is to copy the array, sort it, then get the 0 index value:
var min = idArray.slice().sort(function(a,b){return a - b})[0];
If you don't care about sorting the original array, drop the .slice() part.
Another way is to use Math.min to get the value, then use some to find it in the original array. The benefit of some is that it will stop at the first match:
var min, temp = Math.min.apply(Math, idArray);
idArray.some(function(v){ return temp == v? min = v : false});
console.log(min);
There are pros and cons to each, choose whatever is easiest to maintain.
If it really is an array, you can do it the old fashion way with iteration instead, and return the actual string instead of the parsed number, that way number of decimals is not important.
var idArray = ["98.40", "111.46", "144.47", "180.48", "217.49", "284.50", "424.51", "571.52", "1887.53", "1960.54", "1972.55", "2118.56", "2167.57", "2467.58", "2480.59", "2488.60", "2662.61", "2671.62", "2767.63", "2982.64", "3168.65", "3263.66", "3295.67", "3369.68", "3579.69", "3592.70", "3600.71", "3605.72", "3620.73", "3646.74", "3852.75", "3857.76", "4031.77", "4489.78", "4975.79"];
var result = idArray[0];
idArray.forEach(function(x) {
if (parseFloat(x) < result) result = x; // find smallest number as string instead
});
document.body.innerHTML = result;
or, you could just sort the array and get the first item (I sliced it to not modify the original)
var result = idArray.slice().sort(function(a,b) {
return a - b;
}).shift();
or, use Array.reduce
var result = idArray.reduce(function (a,b) {
return parseFloat(a) < parseFloat(b) ? a : b;
});
Try:
var roundedResult = parseFloat(result).toFixed(2);
The trailing zero has no importance and hence it is truncated. So you have no other go other than storing it as a string.
var result = Math.min.apply(null, idArray);
result = (result+"").test(/\.\d\d$/) ? result : result + "0"
Applying Math.min will always coerce your answer to a number, if you coerce it back to a string you loose any trailing zeros. As others have suggested if you know you will always have a fixed number of digits after the decimal you could use .toFixed.
A better solution that doesn't rely on having a fixed number of decimal points would be to use .reduce:
var result,
idArray = ["98.40", "111.46", "144.47", "180.48", "217.49", "284.50", "424.51", "571.52", "1887.53", "1960.54", "1972.55", "2118.56", "2167.57", "2467.58", "2480.59", "2488.60", "2662.61", "2671.62", "2767.63", "2982.64", "3168.65", "3263.66", "3295.67", "3369.68", "3579.69", "3592.70", "3600.71", "3605.72", "3620.73", "3646.74", "3852.75", "3857.76", "4031.77", "4489.78", "4975.79"];
result = idArray.reduce(function (prev, cur) {
if (+prev < +cur) {
return prev;
} else {
return cur;
}
});
console.log(result); // "98.40"
A quick explanation of what this does:
.reduce iterates over the array and calls the provided function once for each item in the array.
This code just uses the first two parameters available in the function, but there are a couple of others available too. The first parameter is the value returned from the previous call (prev, which will be undefined on the first call). The second parameter will be the value of the current item in the array (cur).
Before comparing the the two they are each coerced from strings to numbers using the Unary plus operator.
If prev is smaller it is returned and the next time the function runs prev will be the same, otherwise cur is returned and become the new value of prev on the next call. It is important to note that when the variables were coerced to compare them that just changed the values being compared in the conditional statement, it did not change the actual value stored in the variable, it remains a string.
After the function has been called on the last item in the array the final value of prev is returned and stored in result.
You could shorten it a little using a ternary statement:
result = idArray.reduce(function (prev, cur) {
return +prev < +cur ? prev : cur;
});
If you aren't afraid to use ES6 syntax (not all browsers currently support it) you could make it even shorter with a arrow function:
result = idArray.reduce((prev, cur) => +prev < +cur ? prev : cur);
The one potential (but unlikely) problem with this approach is that it coerces prev every time it makes a comparison. This adds a tiny bit of overhead to each step in the loop. If performance is a concern it would be better to get away from trying to do it with a one-liner and write a function to do it:
var arrayMin = function (arr) {
var i,
len,
prev, // prev and cur will hold numbers that are coerced from strings
cur, // once when they are first encountered
minIndex; // keep track of the index of the smallest item rather
// than copying a string every time we find a smaller number
prev = +arr[0];
minIndex = 0;
for (i = 1, len = arr.length; i < len; i += 1) {
cur = +arr[i];
if (cur < prev) {
prev = cur;
minIndex = i;
}
}
return arr[minIndex];
};
var result = arrayMin(idArray);

Categories