Merge two arrays at a specific index [closed] - javascript

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);

Related

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) : [];
}

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]));

How can I insert array in the middle of another array in es6?

I have two arrays:
let a = [1, 3, 5];
let b = [2, 4];
I need to put second array into first one after second element, so this is result:
[1, 3, 2, 4, 5]
What is the best way to insert second array into first in es6?
It can be easily solved using concat operation, but I am looking for nice way of doing it in es6.
If you want to insert the second array at specific index, you can use splice function and spread operator.
var a = [1, 3, 5];
var b = [2, 4, 6];
a.splice(2, 0, ...b);
console.log(a); // [1, 3, 2, 4, 6, 5]
Use Array#splice method with spread syntax.
a.splice(2, 0, ...b)
let a = [1, 2, 5];
let b = [3, 4];
a.splice(2, 0, ...b);
console.log(a);
I think this is the answer you're looking for:
function frankenSplice(arr1, arr2, n) {
let arr3 = [...arr2];
arr3.splice(n, 0, ...arr1);
return arr3;
}

remove common elements of two arrays in jquery

I want to remove common elements of two arrays in jquery.
I have two arrays:
A = [0,1,2,3]
B = [2,3]
and result should be [0, 1].
Please help
You can filter array A by checking its elements position in array B:
C = A.filter(function(val) {
return B.indexOf(val) == -1;
});
Demo
ES6 version of Milind Anantwar's answer. May require Babel.
const A = [1, 2, 3, 4];
const B = [2, 4];
const C = A.filter(a => !B.includes(a));
console.log(C) // returns [1, 3]
Use the Set type from ES6. Then the spread operator to build an array from the Set. A Set type can only hold unique items.
const A = [1, 2, 3, 4];
const B = [2, 4];
const C = [...new Set(A,B)];
console.log(C);
(4) [1, 2, 3, 4]
Checkout the library underscore.js.
Say you have two arrays,
var a = [0,1,2,3];
var b = [2, 3];
First find the union.
var all = _.union(a, b);
Then find the intersection.
var common = _.intersection(a, b);
The final answer should be the difference between the union, and the intersection.
var answer = _.difference(all, common)

Categories

Resources