I have an array with a list of objects. I want to split this array at one particular index, say 4 (this in real is a variable). I want to store the second part of the split array into another array. Might be simple, but I am unable to think of a nice way to do this.
Use slice, as such:
var ar = [1,2,3,4,5,6];
var p1 = ar.slice(0,4);
var p2 = ar.slice(4);
You can use Array#splice to chop all elements after a specified index off the end of the array and return them:
x = ["a", "b", "c", "d", "e", "f", "g"];
y = x.splice(3);
console.log(x); // ["a", "b", "c"]
console.log(y); // ["d", "e", "f", "g"]
use slice:
var bigOne = [0,1,2,3,4,5,6];
var splittedOne = bigOne.slice(3 /*your Index*/);
I would recommend to use slice() like below
ar.slice(startIndex,length);
or
ar.slice(startIndex);
var ar = ["a","b","c","d","e","f","g"];
var p1 = ar.slice(0,3);
var p2 = ar.slice(3);
console.log(p1);
console.log(p2);
const splitAt = (i, arr) => {
const clonedArray = [...arr];
return [clonedArray.splice(0, i), clonedArray];
}
const [left, right] = splitAt(1, [1,2,3,4])
console.log(left) // [1]
console.log(right) // [2,3,4]
const [left1, right1] = splitAt(-1, [1,2,3,4])
console.log(left1) // []
console.log(right1) // [1,2,3,4]
const [left2, right2] = splitAt(5, [1,2,3,4])
console.log(left1) // [1,2,3,4]
console.log(right1) // []
Some benefits compared to other solutions:
You can get the result with a one liner
When split index is underflow or overflow, the result is still correct. slice will not behave correctly.
It does not mutate the original array. Some splice based solutions did.
There is only 1 splice operation, rather than 2 slice operations. But you need to benchmark to see if there is actual performance difference.
You can also use underscore/lodash wrapper:
var ar = [1,2,3,4,5,6];
var p1 = _.first(ar, 4);
var p2 = _.rest(ar, 4);
Simple one function from lodash:
const mainArr = [1,2,3,4,5,6,7]
const [arr1, arr2] = _.chunk(mainArr, _.round(mainArr.length / 2));
const splitArrayByIndex = (arr, index) => {
if (index > 0 && index < arr.length) {
return [arr.slice(0, index), arr.slice(-1 * (arr.length - index))]
}
}
const input = ['a', 'x', 'c', 'r']
const output = splitArrayByIndex(input, 2)
console.log({ input, output })
Related
Looking to search a value in an array of array and returning index. Most of the answers are array of objects. So I am looking to search for eg 22 and get 2 as the index where the value was found
Here is the code pen
https://codesandbox.io/s/lodash-playground-array-pzzhe
const arr = [["a","b"],["f","r"],["r",22,"t"]];
console.log("arr", arr);
You could take plain Javascript with Array#findIndex with Array#includes.
var array = [["a", "b"], ["f", "r"], ["r", 22, "t"]],
value = 22,
index = array.findIndex(a => a.includes(value));
console.log(index);
Option 1 Use findIndex
const arr = [["a","b"],["f","r"],["r",22,"t"]];
console.log(arr.findIndex(a => a.includes(22)));
Option 2: Use functions indexOf and includes:
const arr = [["a","b"],["f","r"],["r",22,"t"]];
// find element
const element = arr.find(a => a.includes(22));
// find element index
const currentIndex = arr.indexOf(element)
console.log(currentIndex);
indexOfFlat = (val, array) => array.findIndex(_arr => _arr.includes(val));
const arr = [["a","b"],["f","r"],["r",22,"t"]];
console.log("arr", arr);
console.log("index", indexOfFlat(22, arr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.min.js"></script>
In case you would actually need the sub-array in which the value was found, you could also use Array.find and its index and get both:
const arr = [["a","b"],["f","r"],["r",22,"t"]];
let index, subArr = arr.find((x,i) => x.includes(22) && ~(index=i))
console.log('sub-array: ', subArr)
console.log('index: ', index)
var hasDuplicates = "eyes";
var noDuplicates = new Set(hasDuplicates); // {"e", "y", "s"}
console.log(Object.keys(noDuplicates)); // []
console.log(Object.values(noDuplicates)); // []
I basically want to access the 'e', 'y', and the 's' of the set called 'noDuplicates'.
var setToArray = [];
for (spot in noDuplicates) {
setToArray.push(Object.keys(noDuplicates)[spot])
}
You can use array spread syntax to convert a Set to array:
var hasDuplicates = "eyes";
var noDuplicates = new Set(hasDuplicates); // {"e", "y", "s"}
var setToArray = [...noDuplicates];
console.log(setToArray);
You can also use Set.forEach() or a for...of loop to access the Set's values directly:
var hasDuplicates = "eyes";
var noDuplicates = new Set(hasDuplicates); // {"e", "y", "s"}
noDuplicates.forEach(v => console.log(v));
for(const v of noDuplicates) {
console.log(v);
}
noDuplicates is a Set which provides an iterator. Simply use for...of or the spread operator [... noDuplicates] instead of for...in. Better yet, convert your set into an array directly with Array.from:
let setToArray = Array.from(new Set([1, 1, 1, 2, 2]));
console.log(setToArray);
I wanted to join 2 arrays of the same length. However I want to join each element of with it's counterpart and produce a new array with the combined values.
// will always be string
var array = [a, b, c, d]
// Will always be number
var array2 = [1, 2, 0, 4,]
var output = [a1, b2, c0, d4]
I then want to edit the output array removing any values of 0.
So my final output should be:
var result = [a1, b2, d4]
Any thoughts and suggestions much appreciated.
Use map and filter
var result = array.map( (s, i) => [s , array2[i]] ) //combine values
.filter( s => s[1] != 0 ) //filter out 0s
.map( s => s.join("") ); //join them
Demo
// will always be string
var array = ["a", "b", "c", "d"];
// Will always be number
var array2 = [1, 2, 0, 4, ];
var result = array.map((s, i) => [s, array2[i]]) //combine values
.filter(s => s[1] != 0) //filter out 0s
.map(s => s.join("")); //join them
console.log(result);
Check this repl: https://repl.it/#Freundschaft/MeagerNocturnalFormats
// will always be string
var array = ["a", "b", "c", "d"]
// Will always be number
var array2 = [1, 2, 0, 4,]
function joinArraysCustom (firstArray, secondArray){
if(firstArray.length !== secondArray.length){
throw new Error('Arrays must match');
}
return firstArray.map(function(value, index){
return "" + value + secondArray[index];
}).filter(value => !value.endsWith('0'))
}
console.log(joinArraysCustom (array, array2));
You may use .reduce() and .push():
var arr1 = ['a', 'b', 'c', 'd'];
var arr2 = [1, 2, 0, 4];
function createArray(s, n) {
return n.reduce((a, c, i) => (
/* combine and push if current value is not zero
* otherwise return same array
*/
c != 0 ? (a.push(c + s[i]), a) : a
), []);
}
console.log(createArray(arr1, arr2));
Useful Resources:
Array.prototype.reduce()
Array.prototype.push()
Arrow functions
Comma Operator
There are 2 arrays:
var arr1 = ["a", "b", "c"];
var arr2 = ["k", ,"l","m","n"];
Need some standart function that returns:
var arr3=["k","b","l"];
This one is too slow:
function join_arrays(arr1,arr2)
{
var arr3=[];
for(var i=0;i<arr1.length;i++)
if(arr2[i]==undefined)
arr3[i]=arr1[i];
else
arr3[i]=arr2[i];
return arr3;
}
You could do the following:
var arr1 = ["a", "b", "c"];
var arr2 = ["k",undefined,"l","m","n"];
var arr3 = [];
function join_arrays(arr1,arr2){
arr3 = arr2;
var i = arr3.indexOf(undefined);
while(i !=- 1){
arr3[i] = arr1[i];
i = arr3.indexOf(undefined);
}
return arr3;
}
However there is a little caveat here, as far as my testing in JSBin showed me, which is that you have to have set the empty values that are gonna be replaced to undefined explicitly as I did in my example. If this is not optimal for you, there might be a better way than what I showed here.
Hopefully this runs faster than your code, as it will only go through the loop as many times as needed to do the replacements and will fill arr3 with arr2 right away.
UPDATE:
Bear in mind that, while the above function works, it is unsafe because when the second array has empty elements in an index that is not present in the first one, it will cause an error. Therefore you could do something like this:
function join_arrays(arr1,arr2){
arr3=arr2;
var i = arr3.indexOf(undefined);
while(i!=-1 && i<arr1.length){
arr3[i]=arr1[i];
i=arr3.indexOf(undefined);
}
return arr3;
}
So for var arr2 = ["k",undefined,undefined,"l","m","n",undefined] result will be ["k", "b", "c", "l", "m", "n", undefined] with this method, instead of getting an error or infinite loop!
With use standard functions, it's can be faster.
let arr1 = ["a", "b", "c"];
let arr2 = ["k", ,"l","m","n"];
arr1.map((e,i)=>arr2[i]==undefined?e:arr2[i])
Probably this single liner should do your job.
var arr3 = arr1.forEach((e,i) => arr2[i] === void 0 ? arr3.push(e): arr3.push(arr2[i]));
Here is a sample of what I would like to do
function test(r){
var arr = ['d','e','f'];
r.push(arr);
/*
More Code
*/
return r;
}
var result = test(['a','b','c']);
alert(result.length);//I want this to alert 6
What I need to do is pass in an array and attach other arrays to the end of it and then return the array. Because of passing by reference I cannot use array.concat(array2);. Is there a way to do this without using something like a for loop to add the elements one by one. I tried something like r.push(arr.join()); but that did not work either. Also, I would like the option of having objects in the arrays so really the r.push(arr.join()); doesn't work very well.
>>> var x = [1, 2, 3], y = [4, 5, 6];
>>> x.push.apply(x, y) // or Array.prototype.push.apply(x, y)
>>> x
[1, 2, 3, 4, 5, 6]
Alternatively using destructuring you can now do this
//generate a new array
a=[...x,...y];
//or modify one of the original arrays
x.push(...y);
function test(r){
var _r = r.slice(0), // copy to new array reference
arr = ['d','e','f'];
_r = _r.concat(arr); // can use concat now
return _r;
}
var result = test(['a','b','c']);
alert(result.length); // 6
This is emulbreh's answer, I'm just posting the test I did to verify it.
All credit should go to emulbreh
// original array
var r = ['a','b','c'];
function test(r){
var arr = ['d','e','f'];
r.push.apply(r, arr);
/*
More Code
*/
return r;
}
var result = test( r );
console.log( r ); // ["a", "b", "c", "d", "e", "f"]
console.log( result === r ); // the returned array IS the original array but modified