I have two arrays (a,b) and my task is to find the difference of their volumes i.e. i have to multiply all elements of array a, then do the same for array b and then subtract the two to find the difference.
I tried using forEach() and reduce() in conjuction with arguments but it seems that the last element of each array is left out and what I get as output is NaN.
This is my code
function findDifference(a, b) {
var args = Array.prototype.slice.call(arguments);
var results = [];
args.forEach(function(argument){
return argument.reduce(function(a,b){
results.push(a*b);
});
});
return results;
}
and this is my output for findDifference([3, 2, 5], [1, 4, 4]);
[6, NaN, 4, NaN]
Looks like the multiplication stops with the second element of each array. Any ideas?
Why not just multiply the given arrays and take the delta of the results?
function findDifference(a, b) {
return [a, b]
.map(a => a.reduce((a, b) => a * b))
.reduce((a, b) => a - b);
}
console.log(findDifference([3, 2, 5], [1, 4, 4]));
With arguments.
function findDifference(a, b) {
return Array.prototype
.map.call(arguments, a => a.reduce((a, b) => a * b))
.reduce((a, b) => a - b);
}
console.log(findDifference([3, 2, 5], [1, 4, 4]));
Instead of storing each multiplication in result array, you can store the result of all the multiplication of each array in result array.
function findDifference(a, b) {
var args = Array.prototype.slice.call(arguments);
var results = [];
args.forEach(function(argument){
results.push(argument.reduce(function(a,b){
return a*b;
}));
});
return results;
}
console.log(findDifference([3, 2, 5], [1, 4, 4]));
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
Okay so I know there are multiple answers to this question but all of them use different approaches and I'm confused af rn.
The objective is to create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays. The individual helper function is working fine but the code throws an error when I try to run it whole.
Here is my attempt:
function sym(args) {
let totalArguments = [...args];
var helper = function (arr1, arr2) {
return arr1.filter(item => arr2.indexOf(item) === -1).concat(arr2.filter(item => arr1.indexOf(item) === -1));
}
return totalArguments.reduce(helper);}
The input of sym([1, 2, 3],[2, 3, 4]) should be [1, 4]
Your code isn't working because you're only using the first argument:
function sym(args) {
let totalArguments = [...args];
This takes the first argument, args, and makes a shallow copy of the array - which doesn't accomplish anything because you aren't mutating anywhere anyway. If you wanted to accept a variable number of arguments, use argument rest syntax, to collect all arguments in an array:
function sym(...totalArguments) {
function sym(...totalArguments) {
var helper = function(arr1, arr2) {
return arr1.filter(item => arr2.indexOf(item) === -1).concat(arr2.filter(item => arr1.indexOf(item) === -1));
}
return totalArguments.reduce(helper);
}
console.log(sym([1, 2, 3], [2, 3, 4])) // [1, 4]
console.log(sym([1, 2, 3], [2, 3, 4], [0, 1])) // [0, 4], since 1 was duplicated
(There's no need to provide an initial value to the reducer)
Another option whose logic will probably be clearer to read and understand would be to iterate over all arrays and reduce into an object that keeps track of the number of times each number has occurred. Then, take the entries of the object, and return an array of the keys whose values are 1:
function sym(...args) {
const counts = args.reduce((a, arr) => {
arr.forEach((num) => {
a[num] = (a[num] || 0) + 1;
});
return a;
}, {});
return Object.entries(counts)
.filter(([, count]) => count === 1)
.map(([key]) => key);
}
console.log(sym([1, 2, 3], [2, 3, 4])) // [1, 4]
console.log(sym([1, 2, 3], [2, 3, 4], [0, 1])) // [0, 4], since 1 was duplicated
I'm trying to sort an array of arrays with integers inside, for example:
var array = [[123, 3], [745, 4], [643, 5], [643, 2]];
How can I sort it in order to return something like the following?
array = [[745, 4], [643, 2], [643, 5], [123, 3]];
You can pass a custom comparison function to Array.prototype.sort(), like so:
var sortedArray = array.sort(function(a, b) { return a - b; });
This would sort an array of integers in ascending order. The comparison function should return:
an integer that is less than 0 if you want a to appear before b
an integer that is greater than 0 if you want b to appear before a
0 if a and b are the same
So, for this example you would want something like:
var sortedArray = array.sort(function(a, b) {
return b[0] - a[0];
});
If you wanted to sort on both elements of each sub-array (ie. sort by the first element descending, then if they are the same then sort by the second element descending), you could do this:
var sortedArray = array.sort(function(a, b) {
if (a[0] == b[0]) {
return a[1] - b[1];
}
return b[0] - a[0];
});
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort for more info.
You can use sort method and first sort by first elements and then by second.
var array = [[123, 3], [745, 4], [643, 5], [643, 2]];
array.sort(([a, b], [c, d]) => c - a || b - d);
console.log(array)
Assuming you want to sort by the first index in your example, the sort function exists to solve your problem.
let ans = [[123, 3], [745, 4], [643, 5], [643, 2]].sort( (a, b) => {
return b[0] - a[0]
})
console.log(ans)
A solution for the arrays with generic lengths (not limited to 2 or equal) can be as below:
array.sort((a,b)=>
{
for(let i=0;i<a.length && i<b.length;i++){
if(a[i]!==b[i]){
return a[i]-b[i];
}
}
return a.length-b.length;
};
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);
Given an array, [1, 2, 3, 4, 5], what is the most efficient method for pairing up each of the items sequentially, like so: [[1,2], [2,3], [3,4], [4,5]]?
I've been trying to use the reduce method but to no avail and want something elegant.
Use simple for loop
var data = [1, 2, 3, 4, 5];
var res = [];
for (var i = 0; i < data.length-1; i++) {
res.push(data.slice(i, i+2));
}
console.log(res);
With Array#reduce method
console.log(
[1, 2, 3, 4, 5].reduce(function(a, b, i) {
if (i == 1) return [[a, b]];
a.push([a[a.length - 1][1], b]);
return a
})
)
With Array#reduce method with initial value as empty array
console.log(
[1, 2, 3, 4, 5].reduce(function(a, b, i, arr) {
arr[i + 1] !== undefined && a.push([b, arr[i + 1]])
return a
}, [])
)
To answer the "elegant" bit... ;)
let pairwise = function *(it) {
var
a = it[Symbol.iterator](),
b = it[Symbol.iterator]();
b.next();
for (var x of b) {
yield [a.next().value, x]
}
};
console.log(Array.from(pairwise([1,2,3,4,5])))
Using lodash for given array:
var result = _.chunk( _.sortBy(array.concat(_.slice(array, 1, array.length - 1))), 2);
Check jsfiddle
So if array = [1,2,3,4,5] we have steps:
_.slice(array, 1, array.length - 1)
// = [2,3,4]
array.concat(_.slice(array, 1, array.length - 1)
// = [1,2,3,4,5].concat([2,3,4]) = [1,2,3,4,5,2,3,4]
_.sortBy(array.concat(_.slice(array, 1, array.length - 1))
// _sortBy([1,2,3,4,5,2,3,4]) = [1,2,2,3,3,4,4,5]
_.chunk( _.sortBy(array.concat(_.slice(array, 1, array.length - 1))), 2)
// _chunk([1,2,2,3,3,4,4,5],2) = [[1,2],[2,3],[3,4],[4,5]]
Another short solution using Array.forEach and Array.push functions:
var arr = [1, 2, 3, 4, 5], pairs = [];
arr.forEach((v, k, arr) => arr[k+1] && pairs.push([v, arr[k+1]]));
console.log(JSON.stringify(pairs)); // [[1,2],[2,3],[3,4],[4,5]]
Using reduce:
const res = [1, 2, 3, 4, 5].reduce(
([b, acc], a) => [a, acc.concat([[b, a]])]
, [null, []])[1].slice(1)
console.log(res)
The seed of reduce is a tuple of two items: [null, []]. null represents the current element in the array and [] is the result.
In the first iteration of reduce:
([b, acc], a) => ... b = null and acc = []
The function produces a new tuple, the first item in the tuple is the current element of the array and the second item is the result. In the second iteration:
([b, acc], a) => ..., b = 1 and acc = [[null, 1]]
The second iteration will add (concat) [1, 2] to the result (acc).
In the third iteration:
([b, acc], a) => ..., b = 2 and acc = [[null, 1], [1, 2]]
And so on so forth:
const trace = (x, y) => {
console.log(x);
return y;
}
const json = x => JSON.stringify(x)
const res = [1, 2, 3, 4, 5].reduce(
([b, acc], a) => trace(
`a = ${a}, b = ${b} acc = ${json(acc)} ++ ${json([[b, a]])}`
, [a, acc.concat([[b, a]])]
)
, [null, []]) // seed
// the result is a tuple `[currentElement, finalResult], we extract finalResult here
[1]
// -1 element of the original array was null (check the seed), let's remove it from the result
.slice(1)
console.log(res)
We can think about the problem another way: we are kind of joining the elements of the same array with each other into tuples. Using Ramda zip function is elegant but has a performance tradeoff because we go thru the list twice:
const arr = [1, 2, 3, 4, 5]
const res = R.zip(arr, R.drop(1, arr))
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.21.0/ramda.min.js"></script>
Reduce is most elegant way to do that.
[1,2,3,4,5].reduce((a,b,c) => {
a.push([c,b]);
return a;
}, [])