How to get the head and rest of an array in JavaScript? - javascript

I have an array and would like to get its head and the rest. How do I do this using a destructuring assignment? Is this even possible?
If the array has only two elements, it's pretty easy:
const [head, rest] = myArray;
But what if it contains more than two entries?

You can use spread syntax for that.
const [head, ...rest] = myArray;
var myArray = [1, 2, 3, 4, 5, 6];
const [head, ...rest] = myArray;
console.log(head);
console.log(rest);

Thay way:
const [head, ...rest] = myArray;

With the spread syntax ..., all other items goes into the rest array.
const [head, ...rest] = [1, 2, 3, 4, 5];
console.log(head);
console.log(rest);

You can do like this
const [car, ...cdr] = [1, 2, 3, 4, 5];
console.log(car); // 1
console.log(cdr); // [2, 3, 4, 5]
For more details, refer this link
Hope this helps :)

Accoding to Destructing assignment (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) :
var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2

Related

How insert an array inside another array

Is it possible to insert an array inside another keeping its original array form? I looked on google and didn't find what I wanted, so I'll try here. Should look like this:
arr1 = [1, 2 , 3]
arr2 = [4, 5, 6]
console.log(arr3) // [[1, 2, 3], [4, 5, 6]]
Create a new array that references your other arrays...
const arr3 = [arr1, arr2];
console.log(arr3);
// [[1, 2, 3], [4, 5, 6]]
Or this one use array.push()
let arr1 = [1, 2 , 3]
let arr2 = [4, 5, 6]
let arr3= []
arr3.push(arr1,arr2)
console.log(arr3)
Yes its possible like the below way
var arr1 = new Array (1, 2, 3);
var arr2 = new Array (4, 5, 6);
var arr3 = new Array();
arr3[0] = arr1;
arr3[1] = arr2;
console.log(JSON.stringify(arr3))
Yes, absolutely, it's possible:
const arr1 = [1, 2 , 3]
const arr2 = [4, 5, 6]
const arr3 = []
arr3.push(arr1)
arr3.push(arr2)
console.log(arr3)
The new array holds the references to arr1 and arr2. Even if the references to arr1 and arr2 become unaccessible, the content of these array will not be garbage collected if arr3 is accessible.
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];
const concat = (...arrs) => arrs;
console.log(JSON.stringify(concat(arr1, arr2)));
console.log(JSON.stringify(concat(arr1, arr2, arr3)));

How to compare two arrays and add/remove elements depending on their difference?

Let's say I have two arrays, where array1 is always changing:
First case:
array1 = [1, 2, 3, 4, 5]
array2 = [1, 2, 3]
How can I compare them and add 4 and 5 into array2?
I am getting the difference between them doing:
let difference = array1.filter(x => !array2.includes(x));
and then doing array2.push(difference), so array2 is now equal to array1, right?
Second case:
array1 = [1, 2, 8, 9]
array2 = [1, 2, 3]
So now I need to remove 3 from array2, and add 8 and 9, how can I do this?
EDIT: I need this because I'm getting array1 from a server(they are chats) and it's dynamically changing every 5 sec, and this is problem. I need to keep the elements I already have so they won't "update" and only change the one getting deleted or added. Hope this makes sense.
First case will not work as aspectedlooking at the code,
to achive what you want you have to write:
difference.forEach((x) => array2.push(x));
instead of:
array2.push(difference)
for the second one if you want to remove a record in array2 because is missing in array1 you need to control each value of array2 in array1 and remove if not exists by ID
var array1 = [1, 2, 8, 9];
var array2 = [1, 2, 3];
//here i build difference2 collecting the value of array2 that miss on array1
let difference2 = array2.filter((x) => !array1.includes(x));
//here with splice and indexOf i remove every value collected before
difference2.forEach((x) => array2.splice(array2.indexOf(x), 1));
//following code is to add the 8 and 9
let difference = array1.filter((x) => !array2.includes(x));
difference.forEach((x) => array2.push(x));
console.log(array2);
//the result [1,2,8,9]
let array1 = [1, 2, 3, 4, 5];
let array2 = [1, 2, 3];
let filteredArray = array2.filter((a) => array1.includes(a));
let secFilteredArray = array1.filter((a) => !filteredArray.includes(a));
console.log(filteredArray.concat(secFilteredArray));
You could take a Set and delete seen items and add the rest to the array.
const
array1 = [1, 2, 8, 9],
array2 = [1, 2, 3],
set1 = new Set(array1);
let i = array2.length;
while (i--) if (!set1.delete(array2[i])) array2.splice(i, 1);
array2.push(...set1);
console.log(array2);
Just use another filter and combine the two arrays.
const array1 = [1, 2, 8, 9];
let array2 = [1, 2, 3];
const inArrOne = array1.filter(x => !array2.includes(x));
const inBothArr = array2.filter(x => array1.includes(x));
array2 = [...inBothArr, ...inArrOne];
console.log(array2);
I would avoid much built-in or third party compare functions since I am not sure what I am dealing with. This could be refactored and optimized more if the array1 is guaranteed to have an ordered list.
let localArray = [1, 2, 3, 4, 5],
lastServerArray = [];
/**
* Compares "fromArr" to "targetArr"
* #param fromArr Array of elements
* #param targetArr Array of elements
* #returns List of elements from "fromArr" that do not happen in "targetArr"
*/
const compArr = (fromArr, targetArr) => {
const result = [];
for (let i = 0, len = fromArr.length; i < len; i++) {
const elem = fromArr[i],
targetIdx = targetArr.indexOf(elem);
if (!~targetIdx && !~result.indexOf(elem)) {
// Element do not exist in "targetArr" and in current "result"
result.push(elem);
}
}
return result;
}
const updateLocalArray = (serverArray = []) => {
if (JSON.stringify(lastServerArray) === JSON.stringify(serverArray)) {
console.log('Nothing changed from server, skip updating local array');
return localArray;
}
lastServerArray = serverArray;
const notExistentLocalElems = compArr(serverArray, localArray), // Elements that do not exists in local array
notExistentServerElems = compArr(localArray, serverArray); // Elements that do not exists in server array
// Do something to those "notExistentLocalElems" or "notExistentServerElems"
// ---
// Sync server array to local array
// Remove elements that is not on server.
localArray = localArray.filter(elem => !~notExistentServerElems.indexOf(elem));
console.log('These elements removed from localArray', notExistentServerElems);
// Append elements that is on server.
localArray.push(...notExistentLocalElems);
console.log( 'These elements added into localArray', notExistentLocalElems);
return localArray;
}
updateLocalArray([1, 2, 3]);
console.log(`1. server sends [1, 2, 3] -- local becomes`, localArray);
updateLocalArray([3, 4, 5, 6]);
console.log(`2. server sends [3, 4, 5, 6] -- local becomes`, localArray);
updateLocalArray([5, 5, 4, 2, 7]);
console.log(`3. server sends [5, 5, 4, 2, 7] -- local becomes`, localArray);
updateLocalArray([0, 0, 1, 2]);
console.log(`4. server sends [0, 0, 1, 2] -- local becomes`, localArray);
You could do like this if you want to mutate array2:
let array1 = [1, 2, 8, 9];
let array2 = [1, 2, 3];
let valuesToAdd = array1.filter(x => !array2.includes(x));
let indexesToDelete = Object.entries(array2).filter(([, x]) => !array1.includes(x)).map(([i]) => i);
// Reverse iteration to preserve indexes while removing items
indexesToDelete.reverse().forEach(i => array2.splice(indexesToDelete[i], 1));
array2.push(...valuesToAdd);
console.log(array2);

How to remove first array element using the spread syntax

So I have an array, ex. const arr = [1, 2, 3, 4];. I'd like to use the spread syntax ... to remove the first element.
ie. [1, 2, 3, 4] ==> [2, 3, 4]
Can this be done with the spread syntax?
Edit: Simplified the question for a more general use case.
Sure you can.
const xs = [1,2,3,4];
const tail = ([x, ...xs]) => xs;
console.log(tail(xs));
Is that what you're looking for?
You originally wanted to remove the second element which is simple enough:
const xs = [1,0,2,3,4];
const remove2nd = ([x, y, ...xs]) => [x, ...xs];
console.log(remove2nd(xs));
Hope that helps.
Destructuring assignment
var a = [1, 2, 3, 4];
[, ...a] = a
console.log( a )
Is this what you're looking for?
const input = [1, 0, 2, 3, 4];
const output = [input[0], ...input.slice(2)];
After the question was updated:
const input = [1, 2, 3, 4];
const output = [...input.slice(1)];
But this is silly, because you can just do:
const input = [1, 2, 3, 4];
const output = input.slice(1);
You could use the rest operator (...arrOutput) with the spread operator(...arr).
const arr = [1, 2, 3, 4];
const [itemRemoved, ...arrOutput] = [...arr];
console.log(arrOutput);

How does JavaScript array.reverse() works under the hood?

How can I make a reversed copy of an array using .reverse()? I can't wrap my head around this.
This is my function:
function flipArray(inputArray){
let origArray = inputArray;
let flippedArray = origArray.reverse();
console.log(inputArray);
console.log(origArray);
console.log(flippedArray);
}
flipArray([1,2,3]);
I would expect this...
[1, 2, 3]
[1, 2, 3]
[3, 2, 1]
or this...
[1, 2, 3]
[3, 2, 1]
[3, 2, 1]
but this is what I get...
[3, 2, 1]
[3, 2, 1]
[3, 2, 1]
Why does even inputArray get reversed? Is there another way to do this apart from a for loop?
Array.prototype.reverse reverse the array in-place. It modifies the original array and returns a reference to it. In order to create copies of the original array before it is reversed, you could use Array.prototype.slice, for example:
function flipArray(inputArray){
let origArray = inputArray.slice(0);
let flippedArray = inputArray.slice(0).reverse();
console.log(inputArray);
console.log(origArray);
console.log(flippedArray);
}
flipArray([1,2,3]) now produces
[1,2,3]
[1,2,3]
[3,2,1]

Fast way to push and shift arrays in ES6

I have a data stream which continuously needs to update an array. The array itself is always bigger than the stream which is coming in. This would mean that I have to concat the buffer to the array and shift everything. However, concatenation is slow so I was wondering if there is a fast way of doing this?
Example:
var array = [1,2,3,4,5,6];
var stream = [7,8,9];
array = magicalFunction(array,stream); // outputs [4,5,6,7,8,9]
The array function is used for plotting with ChartJS. It's a rolling plot so as data comes in (it comes in chunks) I have to update the chart by shifting the entire data set.
You could use spread syntax .... But if that is faster than concat ...?
var magicalFunction = (a, s) => [...a.slice(s.length - a.length), ...s],
array = [1, 2, 3, 4, 5, 6],
stream = [7, 8, 9];
array = magicalFunction(array,stream);
console.log(array);
With Array.concat
var magicalFunction = (a, s) => a.slice(s.length - a.length).concat(s);
array = [1, 2, 3, 4, 5, 6],
stream = [7, 8, 9];
array = magicalFunction(array,stream);
console.log(array);
With Array.unshift
var magicalFunction = (a, s) => (s.unshift(...a.slice(s.length - a.length)), s);
array = [1, 2, 3, 4, 5, 6],
stream = [7, 8, 9];
array = magicalFunction(array,stream);
console.log(array);
You can apply a .push:
array.push.apply(array, stream);
or in ES2015 you can use the triple dots:
array.push(...stream)
How about a Spread
var stream = [7,8,9];
var array = [1,2,3,4,5,6, ...stream];
Maybe it's late to answer but you could do this with ES6 like this:
let array = [1, 2, 3, 4, 5, 6];
let stream = [7, 8, 9, 1];
const mergedArray = [...array, ...stream]
// fetch only distinct values
const distinctMergedArray = Array.from(new Set(mergedArray))
let array = [1, 2, 3, 4, 5, 6];
let stream = [7, 8, 9, 1];
//set to get distinct value and spread operator to merge two arrays
const resultArray = new Set([...array, ...stream])

Categories