Related
I'm trying to write a map/reduce to get the average of each array within an array.
For example.
[[1][2,3][4,5,6,7]] => [1, 2.5, 5.5]
Right now this is my code where result is the array of arrays:
result.map(array => {
return array.reduce((a, b) => (a + b)) / array.length;
})
const result = [
[1],
[2, 3],
[4, 5, 6, 7]
]
console.log(result.map(array => {
return array.reduce((a, b) => (a + b)) / array.length;
}))
Any help to get the desired output is much appreciated. As it stands, my output is reducing to an array of NaN's instead of the averages.
You need a closing parentesis.
By using Array#reduce with arrays with unknown length, you need to take a start value, which is in this case of a length of zero the result.
var result = [[1], [2, 3], [4, 5, 6, 7]],
avg = result.map(array => array.reduce((a, b) => a + b, 0) / array.length);
// ^^^ ^
// optional required
console.log(avg);
you must provide a second argument to the reduce function, the initial value of a. So:
result.map(array => {
return array.reduce((a, b) => a + b, 0) / array.length;
});
You may also want to ensure that array.length > 0 before you divide by it
After reading the docs on map method,I still cannot get this to work.
I am trying to use map to get the average of every pair of numbers in an array.Please help me understand whats wrong.
function getAverage(num1,num2){return Math.ceil((num1+num2)/2)};
function a(input){ var b = input.map(getAverage(num1,num2)); return b; }
a([1,2,3,4]) //error num1 is not defined
//expected [2,4]
map projects a function to each element of a list/array, it simply "maps" a function over all the items.
[1, 2, 3].map(function (number) { return number + 1; });
// -> [2, 3, 4]
Therefor, first you need to have pairs of items in your "input" array, so it looks like this:
var numberPairs = [[1, 2], [3, 4]]
Until now, all you have are just single numbers but no pairs.
After conversion, you can use map like this:
numberPairs.map(function (pair) {
return Math.ceil((pair[0] + pair[1]) / 2);
});
This will give:
[2, 4]
as a result.
You can't calculate the average using a map. A mapping pass a function to each element and then returns an array with the same shape. That is not the case, you want to get a value from an array, and you can use the reduce method for that.
// adds two number
const adder = (a,b) => a + b;
// reduces the array adding all numbers and divides
// by the array length
const getAverage = (arr) => arr.reduce(adder)/arr.length;
// outputs 2.5
console.log(getAverage([1,2,3,4]))
You can use reduce() instead of map() to aggregate averages of every n values in the array:
const sum = array => array.reduce((a, b) => a + b, 0)
const getAverage = n => (averages, value, index, array) => index % n === 0
? [...averages, Math.ceil(sum(array.slice(index, index + n)) / n)]
: averages
const result = [1, 2, 3, 4].reduce(getAverage(2), [])
console.log(result)
I have a few arrays in array :
([[10,0],[3,5],[5,8]])
I try substract all inner arrays a - b and then sum results ( example : 10 - 0 = 10, 3-5 = -2, 5-8 = -3, 10+(-2)+(-3) = 5;
My try:
var el;
return array.reduce((a, b) => a - b );
But my result came out Nan, now Im understood, in my code i want substring array from array - bad idea.
I know how do this with using for or something like that, my question is:
how i can do this with use reduce or other ''modern'' method?
Thanks for help.
PS sorry for my English skill ;)
You can use reduce() method like this.
var data = [[10,0],[3,5],[5,8]]
var result = data.reduce((r, e) => r + (e[0] - e[1]), 0);
console.log(result)
Flexible solution, the size of the nested arrays doesn't matter, it will still return a proper result.
const count = (arr) => arr.reduce((s, v) => {
s += v.reduce((a,b) => a - b);
return s;
}, 0);
let arr1 = [ [10, 0], [3, 5], [5, 8] ],
arr2 = [ [5, 4, 1], [3, 5, 5], [5, 8] ];
console.log(count(arr1));
console.log(count(arr2));
Something like this? You were close, but be sure to have an initial value of 0 and dereference the inner arrays into a and b like so:
var array = [[10,0],[3,5],[5,8]];
var result = array.reduce((prev, [a, b]) => prev + (a - b), 0);
console.log(result);
const arr = ([[10,8],[3,5],[5,8]]);
arr.map(pair => pair[0] - pair[1]).reduce((a,b) => a + b)
You could reduce the outer and inner arrays.
var array = [[10, 0], [3, 5], [5, 8]],
result = array.reduce(function (r, a) {
return r + a.reduce(function (x, y) {
return x - y;
})
}, 0);
console.log(result);
I have array of elements as input.all I need is to double the value of array elements.Though it is simple to make use of map to get the solution.I am interested in using reduce.eg:
io: var a = [1,2,3,4,5];
op:[2,4,6,8,10]; .but this is where I ended.
var c = a.reduce( (acc,b) => {
acc =b*2;
console.log(acc);
return acc
},[]);
var arr = [1, 2, 3, 4, 5];
var doubled = arr.reduce(function (memo, val) {
memo.push(val * 2);
return memo;
}, []);
console.log(doubled);
var arr2 = [1, 2, 3, 4, 5];
arr2.reduce(function (memo, val, i) {
memo[i] *= 2;
return memo;
}, arr2);
console.log(arr2);
var arr3 = [1, 2, 3, 4, 5];
arr3.reduce(function (memo, val, i) {
arr3[i] *= 2;
}, null);
console.log(arr3);
In the first solution, reduce starts with an empty array (the second argument provided to it). Then, that array is passed down to next iterations as the first argument (memo) to the function we provided. The second argument is the current element of the iteration. After the doubled value is pushed in the new array, that array is returned so it can be accessed in future iterations as memo.
In the second solution, no new array is created and the initial one is used instead. It is passed to reduce as its second element and later accessed through memo.
The third solution is like the second one except the reduced array is just referenced as it is. Notice that null must be passed as second argument. If nothing is passed, reduce will start from the second element (since there's no initial value) and the first element won't get doubled.
Note
The first time the callback is called, accumulator and currentValue can be one of two values. If no initialValue is provided, then accumulator will be equal to the first value in the array, and currentValue will be equal to the second.
let arrayOfNumbers = [1, 2, 3, 4];
arrayOfNumbers.reduce((accumulator, currentValue, index, array) => {
//code
},initialvalue);
if you miss this initialvalue argument then your index begins from one(1) and the accumulator will have the first value of array.
Hence your array[index] = array[index]*2
For example in such case
arr=[1,2,3,4,5]
output
arr=[1,4,6,8,10]
Now this will be the approach
let arrayOfNumbers = [1, 2, 3, 4];
arrayOfNumbers.reduce((accumulator, currentValue, index, array) => {
console.log(accumulator,currentValue);
array[index] = array[index]*2;
},0);
arr=[1,2,3,4,5]
output
arr=[1,4,6,8,10]
take initialvalue as 0(or any value), so that you can get the index from 0.
if you do this accumulator will get 0 and the index begins from 0 only.
Note
if you don't initialize accumulator value that is initialvalue.
Default
accumulator(initialvalue) will be arr[0]
and index begins from 1
and
if you initialize accumulator value that is initialvalue(argument) then
accumulator(initialvalue) will take that initialvalue and index begins from 0.
As you provided in your last parameter to reduce, acc is an array, although you're treating it like an integer. You'll want something like below:
var c = a.reduce( (acc,b) => {
acc.push(b*2);
console.log(acc);
return acc
},[]);
Try this
var c = a.reduce( (acc,b) => acc.concat(b*2)
,[]);
I'll provide a couple other answers that aren't shown here
1. Using spread syntax
const data =
[1,2,3,4,5];
const double = xs =>
xs.reduce ((ys, x) => [...ys, x * 2], [])
console.log(double(data))
// [ 2, 4, 6, 8, 10 ]
2. Using a destructured parameter with recursion
const data =
[1,2,3,4,5]
// this time we don't need reduce
const double = ([x,...xs]) =>
x === undefined ? [] : [x * 2, ...double(xs)]
console.log(double(data))
// [ 2, 4, 6, 8, 10 ]
3. Tacit (Point-free style)
const data =
[1,2,3,4,5]
const mult = x => y =>
y * x
const reduce = f => acc => ([x,...xs]) =>
x === undefined
? acc
: reduce (f) (f (acc, x)) (xs)
const map = f =>
reduce ((acc, x) =>
[...acc, f (x)]) ([])
// point-free double
const double =
map (mult (2))
console.log (double (data))
// [ 2, 4, 6, 8, 10 ]
Hello I have an array as follows:
[[1,1],[2,8],[3,12],[4,13],[5,23],[6,30],[7,41],[8,44],[9,50]]
So lets say it is the format of [[x,y]]
As you can see the above array, the first element inside inner arrays goes from 1,2...6 which is x, and the second element of inner arrays are 1,8,12,13,23 and 30 which is y.
This is a cumulative array of y and I want to convert it into non-cumulative but with a twist.
I want to convert y to non-cumulative array by getting the difference from the value of y at last 3rd value of x
Therefore I want the final result to be as follows:
[[1,1],[2,8],[3,0],[4,1],[5,11],[6,0],[7,11],[8,14],[9,0]]
I have tried a fiddle here:
https://jsfiddle.net/gxytx6ka/1/
So far I have been able to get the difference between two array elements by some help of Dekel (stackoverflow guy) as you can see in the above fiddle:
$(document).ready(function() {
var old_arr = [ [1, 1], [2, 8], [3, 12], [4, 13], [5, 23], [6, 30], [7, 41], [8, 44], [9, 50] ];
var new_arr = old_arr.reduce(function(a, b, c, d) {
if (a.length) {
a.push([d[c][0], d[c][1] - d[c - 1][1]])
} else {
a = [b]
}
return a;
}, []);
console.log(new_arr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
which outputs:
[[1,1],[2,7],[3,4],[4,1],[5,10],[6,7],[7,11],[8,3],[9,6]]
but I want:
[[1,1],[2,8],[3,0],[4,1],[5,11],[6,0],[7,11],[8,14],[9,0]]
which I am not able to get.
I tried using a%3==0 in if condition, but not working...
Basically I want the final output in an efficient way.
Why reduce? A simple loop does the job perfectly fine:
let a = [[1,1],[2,8],[3,12],[4,13],[5,23],[6,30],[7,41],[8,44],[9,50]];
let out = [],
n = 0,
lastY = 0;
for (let [x, y] of a) {
if (++n % 3 == 0)
lastY = y;
out.push([x, y - lastY]);
}
console.log(JSON.stringify(out))
You could use Array#map, which returns simply an array with the result.
var array = [[1,1], [2,8], [3,12], [4,13], [5,23], [6,30], [7,41], [8,44], [9,50]],
result = array.map(function (a, i) {
(i + 1) % 3 || (this.last = a[1]);
return [a[0], a[1] - this.last];
}, { last: 0 });
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6
var array = [[1,1], [2,8], [3,12], [4,13], [5,23], [6,30], [7,41], [8,44], [9,50]],
result = array.map((l => ([x, y], i) => (++i % 3 || (l = y), [x, y - l]))(0));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
It is possible to do this with reduce — You just need to figure out when to zero-out every third value and when to find the difference between the current value and it's previous (third) value.
Naming parameters with more intelligible names also helps out.
var old_arr = [ [1, 1], [2, 8], [3, 12], [4, 13], [5, 23], [6, 30], [7, 41], [8, 44], [9, 50] ];
var new_arr = old_arr.reduce(function(result, value, index, arr) {
if (index % 3 == 2) {
return result.concat([[value[0], 0]]); // Set every third value to 0.
} else {
var prevIndex = index - (index % 3) - 1;
var prevVal = prevIndex > -1 ? arr[prevIndex][1] : 0;
return result.concat([[value[0], Math.abs(prevVal - value[1])]]);
}
}, []);
console.log(JSON.stringify(new_arr)); // [[1,1],[2,8],[3,0],[4,1],[5,10],[6,0],[7,11],[8,3],[9,0]]
With reduce you can do it like this (also using ES6 arrow function and spread operator):
var arr = [[1,1], [2,8], [3,12], [4,13], [5,23], [6,30], [7,41], [8,44], [9,50]];
var result = arr.reduce( ([arr, v], [x, y], i) =>
[[...arr,[x, i%3==2 ? 0 : y-v]], i%3==2 ? y : v], [[],0])[0];
console.log(result);
Explanation
reduce is called with a double initial value (a pair):
[[],0]
The first element is the array that will accumulate into the final result, and the second value is the current value to which subsequent y values will be offset.
These two values are captured by the argument [arr, v] which is a destructuring assignment (ES6). The reduce callback will always return a new pair like that, with extended arr and (potentially) updated v.
The callback function also takes the current [x, y] pair from the original array. Again this is a destructuring assignment, so you have direct access to x and y variables. The third argument i is the current, zero-based index in the original array.
As said, the callback returns a pair. The first element in that pair is constructed as follows:
[...arr, [x, i%3==2 ? 0 : y-v]]
The ...arr notation spreads the previously collected result elements as a list, and one pair is added to that list: [x, i%3==2 ? 0 : y-v]. The x is just reproduced from the original [x, y], but the y follows the requested logic with the ternary operator: if we are at an index that has a remainder of 2 when divided by 3, then the y value should be 0. Otherwise, it should be offset against the previously set value v.
The second element in the pair, must be the new value for v:
i%3==2 ? y : v
Again, according to the requested logic, v remains unchanged when the remainder is not 2, but otherwise it is set to the current value of y.
So reduce will thus accumulate/update these two values in each iteration, and finally return a pair, of which only the first has our interest, which is why there is [0] at the end.
Notes
As you seemed to be looking for a reduce implementation, that is what I went with, but whenever your output array has just as many elements as your input array (like is the case here) you can also consider to use map as a good alternative (See answer that NinaScholz posted).
If you are open for a less functional programming way, you can also choose to use a for loop and maybe gain a bit of performance.