JavaScript reduce inner array of array and create answer array - javascript

Array of arrays:
list = [[1, 2, 3], [4, 5, 6]];
I want to reduce (combine) each inner array (1+2+3) and (4+5+6) and then put those results 6 and 15 in their own array like [6, 15].
I have below code:
list.reduce((a, b) => a + b);
but it's just strangely combining everything in all the arrays.

You need to iterate both the outer and the inner arrays.
list.map(array => array.reduce((a, b) => a + b))

Use .map() with .reduce():
let list = [[1, 2, 3], [4, 5, 6]];
let reducer = (a, b) => (a + b);
let result = list.map(arr => arr.reduce(reducer));
console.log(result);

You can do it like this
map() with map we iterate on every element of arr.
reduce() - with reduce we reduce each element to a single value.
let arr = [[1,2,3],[4,5,6]];
let op = arr.map(e => e.reduce( (a, b) => a + b, 0) );
console.log(op);

You can also achieve this with Array.from since its second parameter is Array.map function and inside you can do your Array.reduce for the summation:
const data = [[1, 2, 3], [4, 5, 6]]
const result = Array.from(data, x => x.reduce((r,c) => r+c))
console.log(result)

Related

How to add extra values from 2 arrays to end of new array

For example, if I have 2 arrays being:
let array1 = [1,2,3]; and let array2 = [5,6,7,8,9], how would I create a new 3rd array that only contains the elements from array2 that are at the extra indexes (so the new array would only contain [8,9] since they are at index 3 and 4).
Thanks!
You can use the Javascript slice() function
arr1 = [1,2,3]
arr2=[5,6,7,8,9]
arr3 = arr2.slice(arr1.length , arr2.length)
console.log(arr3)
There are plenty of ways to do that, here's a solution that uses slice method with a negative index. That negative index is (array2.length - array1.length) * -1.
const array1 = [1, 2, 3],
array2 = [5, 6, 7, 8, 9],
sliceArray = (a1, a2) => a2.length <= a1.length ? [] : a2.slice((a2.length - a1.length) * -1)
console.log(sliceArray([], [])); // returns: []
console.log(sliceArray([1, 3, 6], [1, 2])); // returns: []
console.log(sliceArray(array1, array2)); // returns: [8, 9]
let array1 = [1,2,3,8,9];
let array2 = [5,6,7];
let array3=array1.length > array2.length ?array1.slice(array2.length,array1.length):array2.slice(array1.length,array2.length)
console.log(array3);
Use ternary operator and slice method
You can use a function that will find the longer array and slice it for you. That way, you don't need to know in advance which array is longer:
function collectExtra (arrayA, arrayB) {
if (arrayA.length === arrayB.length) return [];
const [shorter, longer] = [arrayA, arrayB]
.sort((a, b) => a.length - b.length);
return longer.slice(shorter.length);
}
const array1 = [1,2,3];
const array2 = [5,6,7,8,9];
const result = collectExtra(array1, array2);
console.log(result); // [8, 9]
const result2 = collectExtra(array2, array1);
console.log(result2); // [8, 9]

How to rearrange 3 arrays with according to the elements and return as one array?

I have 3 arrays. For example, given the arrays are
arr1 = [2, 7]
arr2 = [0, 1, 16]
arr3 = [3, 6, 9]
And I would like to rearrange them according to the numbers and output as an array.
result = ['arr2', 'arr2', 'arr1', 'arr3', 'arr3', 'arr1', 'arr3', 'arr2']
I think it might have something to do with looping, but I've no luck after struggling for a while. Is there any way to get the expected result?
You could move the values to an object and take another object for the indices and sort an array of key.
Then take the key at index zero and go on until the index is equal to the length of the array, then stop the iteration.
const
arr1 = [2, 7],
arr2 = [0, 1, 16],
arr3 = [3, 6, 9],
values = { arr1, arr2, arr3 },
result = [],
keys = Object.keys(values),
indices = Object.fromEntries(keys.map(k => [k, 0]));
while (true) {
keys.sort((a, b) => (values[a][indices[a]] ?? Number.MAX_VALUE) - (values[b][indices[b]] ?? Number.MAX_VALUE));
if (indices[keys[0]] === values[keys[0]].length) break;
result.push(keys[0]);
indices[keys[0]]++;
}
console.log(...result);
A shorter approach by mapping entries, sorting and mapping again.
const
arr1 = [2, 7],
arr2 = [0, 1, 16],
arr3 = [3, 6, 9],
result = Object
.entries({ arr1, arr2, arr3 })
.flatMap(([k, a]) => a.map(v => [k, v]))
.sort(([, a], [, b]) => a - b)
.map(([k]) => k);
console.log(...result);
Option 1. Allocate an array whose size is equal to the total count of elements in the 3 arrays. Populate the newly created array with the elements from your 3 small arrays. Then sort the created array.
Option 2. Merge 2 of the 3 arrays to produce a sorted array with elements from the chosen 2 small arrays. Then merged the sorted array from the previous step with the 3rd array to get the array that you need.
Not an elegant solution but maybe something like can help
arr1 = [2, 7]
arr2 = [0, 1, 16]
arr3 = [3, 6, 9]
let concatedArray = [...arr1, ...arr2, ...arr3].sort((a, b) => a - b);
let finalArr = []
concatedArray.forEach(val => {
let doesNumberExist = false;
let arrName = ''
doesNumberExist = arr1.includes(val);
arrName = 'arr1';
if (!doesNumberExist) {
doesNumberExist = arr2.includes(val);
arrName = 'arr2'
}
if (!doesNumberExist) {
doesNumberExist = arr3.includes(val);
arrName = 'arr3'
}
finalArr.push(arrName);
}
)
console.log(finalArr)

Javascript (ES6) way to select/filter objects from and array and remove them from original array [duplicate]

This question already has answers here:
Dividing an array by filter function
(14 answers)
Closed 4 years ago.
Is there a way to filter an array of objects to retrieve an array of the values I need but also remove the filtered values from the original list. Something like this
let array = [1, 2, 3, 4, 5];
const filteredList, listContainingRemainingValues = array.filter(value => value > 3);
Output:
filteredList = [4, 5];
listContainingRemainingValues = [1, 2, 3];
Is there any built in functionality to do this already in Javascript or will i have to roll my own?
You could take an array as temporary storage for the wanted result.
const
array = [1, 2, 3, 4, 5],
[remaining, filtered] = array.reduce((r, v) => (r[+(v > 3)].push(v), r), [[], []]);
console.log(filtered);
console.log(remaining);
Same with lodash's _.partition
const
array = [1, 2, 3, 4, 5],
[filtered, remaining] = _.partition(array, v => v > 3);
console.log(filtered);
console.log(remaining);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Here's one option:
const array = [1, 2, 3, 4, 5];
// Get all the indices we want to keep:
const matchingIndices = array
.map((v, i) => [i, v > 3])
.filter((el) => el[1])
.map((el) => el[0]);
// Filter the input array by indices we want/don't want
const matching = array.filter((v, i) => matchingIndices.indexOf(i) >= 0);
const nonMatching = array.filter((v, i) => matchingIndices.indexOf(i) < 0);
Use 2 filters
let array = [1, 2, 3, 4, 5];
let filteredList = array.filter(value => value > 3);
let listContainingRemainingValues = array.filter(f => !filteredList.includes(f))
console.log(filteredList)
console.log(listContainingRemainingValues)
Here's one of the way using underscore library:
var data = [1, 2, 3, 4, 5]
var x = _.reject(data, function(num){ return num > 3; });
var y = _.difference(data, x);
console.log(x);
console.log(y);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
Sort the array, find the index of your threshold value and then splice it in order to remove the elements from the input array and to return the removed elements:
const array = [1, 2, 3, 4, 5];
// just if the input array is not already sorted
array.sort();
const removedElements = removeAndGet(array, 3);
console.log('input array:', array);
console.log('removed elements:', removedElements)
function removeAndGet(input, thresholdValue) {
const ind = input.findIndex(a => a > thresholdValue);
return ind > -1 ? input.splice(ind) : [];
}

Merge two arrays at a specific index [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Let's say I have an array called array1:
var array1 = [1, 2, 5];
And I have another called array2:
var array2 = [3, 4];
I want to output the result [1, 2, 3, 4, 5] by inserting array2 at index number 2 of array1.
How can achieve this in JavaScript?
EDIT:
More things to note:
Array mutation in place does not matter, either way would be fine.
The order of the array elements does not matter, the task at hand is to merge two arrays at a specified index.
I've come up with one possible implementation:
// merge 'b' with 'a' at index 'i'
function merge(a, b, i=0) {
return a.slice(0, i).concat(b, a.slice(i));
}
var result = merge([1, 2, 5], [3, 4], 2);
console.log(result);
You might try spreading b's elements into splice, which adds a series of arguments at index i (the optional argument removal is ignored with 0). a will be modified in place.
const mergeInPlace = (a, b, i=0) => a.splice(i, 0, ...b);
const a = [1, 2, 5];
const b = [3, 4];
mergeInPlace(a, b, 2);
console.log(a);
If you want to avoid mutation, spread and slice is probably easiest:
const merge = (a, b, i=0) => [...a.slice(0, i), ...b, ...a.slice(i)];
const a = [1, 2, 5];
const b = [3, 4];
console.log(merge(a, b, 2));
If you don't want to mutate the original array you can spread slices out into a new array:
var array1 = [1, 2, 5];
var array2 = [3, 4];
function merge(a1, a2, i){
return [...a1.slice(0,i), ...a2, ...a1.slice(i)]
}
console.log(merge(array1, array2, 2))
// negative indexing too
console.log(merge(array1, array2, -2))
If the goal is just to order them:
array1.concat(array2).sort();
var array1 = [1, 2, 5],
array2 = [3, 4];
let r = array1.concat(array2).sort();
console.log(r);
If the goal is to insert at a certain index:
array1.splice(2,0,array2);
array1.flat();
var array1 = [1, 2, 5],
array2 = [3, 4];
array1.splice(2,0,array2);
let r = array1.flat();
console.log(r);
As an alternative to that you can use a functional approach. I offer this because I find .splice to be an ugly method that mutates the array,is too closely named to slice, and doesn't even return the array you're probably looking for.
let combineAt = (n, a, b) =>
a.reduce((ac, cv, ci) =>
(n === ci) ?
(ac.push(b, cv), ac.flat()) :
(ac.push(cv), ac), []);
combineAt(2,array1,array2);
var array1 = [1, 2, 5],
array2 = [3, 4];
let combineAt = (n, a, b) => a.reduce((ac, cv, ci) => (n === ci) ? (ac.push(b, cv), ac.flat()) : (ac.push(cv), ac), []);
let r = combineAt(2, array1, array2);
console.log(r);

Suming a nested array's indices together with JavaScript map

Working to get a better grasp of nested arrays. I have an array with two arrays nested inside as the indices. I am trying to figure out how to add these. I understand how you would add them if they were separate arrays, but I am wondering how/if possible you can map through a nested array to add the indices.
The current array that I am looking at is
strArr= [[5, 2, 3], [2, 2, 3] ];
If this was two separate arrays I could simply run a map with index as a second parameter such as ...
var arr = [1,2,3,4];
var arr2 = [1,1,1,2,9];
arr.map((a, i) => a + arr2[i]);
However, I am not able to achieve this with the index
strArr.map((a,idx) => a[0][idx] + a[1][idx]) // [Nan, Nan]
The best I can do to get any addition is
return strArr.map(a => a[0] + a[1]) // [7,4]
However, I am not sure why I am only getting [7,4]
You iterate over the outer array, which has a length of 2. Therefore you get a result of two elements.
You could use Array#reduce for the outer array and Array#forEach for the inner arrays and sum the values at a given index.
var strArr= [[5, 2, 3], [2, 2, 3] ];
console.log(strArr.reduce((r, a) => (a.forEach((b, i) => r[i] = (r[i] || 0) + b), r), []));
You can use the .reduce function to sum your indices
var arr = [1, 2, 3, 4];
var arr2 = [1, 1, 1, 2];
var result = arr
.map((item, i) => i + arr2[i])
.reduce((memo, value) => memo + value);
console.debug("res: ", result);
// res: 11
However you will have to handle cases when the array lengths are not equal to eachover or not numerical values
Map each element in the parent array (sub-arrays)
For each sub-array reduce and sum
strArr= [[5, 2, 3], [2, 2, 3] ];
var result = strArr.map((arr)=>arr.reduce((a,b)=>a+b));
console.log(result);
Why not just target/split the original array?
"If this was two separate arrays I could simply run a map with index as a second parameter"
Then make it two separate arrays...
strArr= [[5, 2, 3], [2, 2, 3] ]; /* becomes strArr[0] & strArr[1] */
console.log(strArr[0].map((a, i) => a + strArr[1][i]));

Categories

Resources