I am trying to take the average of successive pairs of ints in a 2d array.
e.g. if the starting array looks like this:
[
[1, 2, 3, 4, 5, 6],
[10, 20, 30, 40, 50, 60]
];
The resulting array should look like:
[
[1.5, 3.5, 5.5],
[15, 35, 55]
]
My method is to loop through each array in turn, using %2 to select every other value, add them together and then push to a new 2d array.
Can anyone guide why the actual result is:
[
[1.5, 3.5, 5.5, 15, 35, 55],
[1.5, 3.5, 5.5, 15, 35, 55]
]
Here is my code:
var data = [
[1, 2, 3, 4, 5, 6],
[10, 20, 30, 40, 50, 60]
];
//create the same number of empty arrays as there are arrays in data.
var averagedCols = new Array(data.length).fill([]);
for (var i = 0; i < data.length; i++) {
for(var j = 0; j < data[i].length; j++) {
if (j%2 === 0) {
var average = (data[i][j] + data[i][j+1])/2;
averagedCols[i].push(average);
}
}
}
console.log(averagedCols);
https://jsbin.com/rogemonave/edit?js,console
Note: jsbin also prints [circular object Array]
when I try to print the whole resulting array, but a quick google seems to say this is a problem with jsbin not my code as this is not happening on my computer. Could still be an issue with my code though.
The problem with your original code is that when you do .fill([])
, you're filling with multiple references of the same empty array - there's only one empty array in memory, which each index of averagedCols
refers to. You can fix this by explicitly creating the array on each iteration with Array.from
:
var data = [
[1, 2, 3, 4, 5, 6],
[10, 20, 30, 40, 50, 60]
];
//create the same number of empty arrays as there are arrays in data.
var averagedCols = Array.from(
{ length: data.length },
() => []
);
for (var i = 0; i < data.length; i++) {
for(var j = 0; j < data[i].length; j++) {
if (j%2 === 0) {
var average = (data[i][j] + data[i][j+1])/2;
averagedCols[i].push(average);
}
}
}
console.log(averagedCols);
Best to only use .fill
when filling an array with primitives - for non-primitives (objects, arrays, and functions), use Array.from
instead.
The logic will probably be easier if you first chunk the array items into pairs, eg [1, 2, 3, 4, 5, 6]
to [[1, 2], [3, 4], [5, 6]]
. Then, all you need is a simple .map
to average each pair:
function toPairs(arr) {
const pairs = [];
for (let i = 0; i < arr.length; i += 2) {
pairs.push(arr.slice(i, i + 2));
}
return pairs;
}
const input = [
[1, 2, 3, 4, 5, 6],
[10, 20, 30, 40, 50, 60]
];
const output = input
.map(toPairs)
.map(arrayOfPairs => arrayOfPairs.map(pair => (pair[0] + pair[1]) / 2));
console.log(output);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With