I have seen some YouTubers not use array.push() to add items to an array but rather do something like:
let item = 3
let array = [1, 2];
array = [...array, item]; // Why not use array.push()?
Is there any difference between the two methods and which one should i use?
Push: Use push when you want to add data in the existing array and don't want to cra
When you use the push method, you are adding the element to the existing one i.e not creating a new array.
The push() method adds one or more elements to the end of an array and
returns the new length of the array. - MDN
const arr = [1, 2, 3, 4, 5];
const returnValue = arr.push(6);
console.log(arr);
console.log(returnValue)
Spread Syntax: Use spread syntax if you want to add elements in new array(it can be from spread or can add more new elements also) but will create a new array []
This is called spread syntax
Spread syntax (...) allows an iterable such as an array expression or
string to be expanded in places where zero or more arguments (for
function calls) or elements (for array literals) are expected, or an
object expression to be expanded in places where zero or more
key-value pairs (for object literals) are expected.
let array = [1, 2];
let item = 3
result = [...array, item];
console.log(result === array);
In the above snippet you are creating a new array and assigning values 1, 2 then you are using spread syntax to spread it into a new array. You can also add new elements also like item whose value is 3.
array.push manipulates the existing array. The latter makes a new copy with the new value.
Array push is used to push items kn exisiting array but if we want a copy of an element of an array as a new array variable- you can use […array] operator.
Related
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
as per document says The filter() method creates a new array with all elements that pass the test implemented by the provided function.
According to document below script should console Learning console.log(Arr[0].name) // Learning
var Arr = [{name:'Learning'},{name:'Questing'}]
var Arr2 = Arr.filter(it=> true);
Arr2[0].name = 'Stack-Over-Flow';
console.log(Arr[0].name) // Stack-Over-Flow
Yes, .filter creates a new array, but the new array is the only new structure that is created. The items inside the array remain unchanged.
With your code, after filtering, you have a new array which contains 2 items, where both of those items are references to the same objects that were in the original array. So, mutating one of the objects in the new array results in the objects in the old array being mutated, because they point to the same object in memory.
If you wanted to avoid this, you'd have to deep clone the array first, perhaps with
const Arr2 = Arr
.filter(it => true)
.map(obj => ({ ...obj }));
.filter does create a new array, but the array of the filtered elements from the old array.
While the element from the old is object, so that new array still keep its reference. To avoid that, you could do a .map to clone the element for the whole new reference
var Arr = [{name:'Learning'},{name:'Questing'}]
var Arr2 = Arr.filter(it=> true).map(el => ({...el}));
Arr2[0].name = 'Stack-Over-Flow';
console.log(Arr[0].name)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
as per document says The filter() method creates a new array with all elements that pass the test implemented by the provided function.
According to document below script should console Learning console.log(Arr[0].name) // Learning
var Arr = [{name:'Learning'},{name:'Questing'}]
var Arr2 = Arr.filter(it=> true);
Arr2[0].name = 'Stack-Over-Flow';
console.log(Arr[0].name) // Stack-Over-Flow
Yes, .filter creates a new array, but the new array is the only new structure that is created. The items inside the array remain unchanged.
With your code, after filtering, you have a new array which contains 2 items, where both of those items are references to the same objects that were in the original array. So, mutating one of the objects in the new array results in the objects in the old array being mutated, because they point to the same object in memory.
If you wanted to avoid this, you'd have to deep clone the array first, perhaps with
const Arr2 = Arr
.filter(it => true)
.map(obj => ({ ...obj }));
.filter does create a new array, but the array of the filtered elements from the old array.
While the element from the old is object, so that new array still keep its reference. To avoid that, you could do a .map to clone the element for the whole new reference
var Arr = [{name:'Learning'},{name:'Questing'}]
var Arr2 = Arr.filter(it=> true).map(el => ({...el}));
Arr2[0].name = 'Stack-Over-Flow';
console.log(Arr[0].name)
I'm making shopping cart,and I am a little bit confused. There is a counter which counts number of current product. For example: the user can buy 5 book or more. So , I need to make a function which adds the element аs many times as the user will select it.
I made something like this:
[...state.shoppingCart, new Array(state.booksNumber).fill({...action.book})]
But of course it makes a new array in array... So how can I just add elements to an array without deleting old elements or creating a new array inside the array?
I need a functional way, no loops.
const newArray = new Array(state.booksNumber).fill({...action.book})
[...state.shoppingCart, ...newArray]
Simply use the spread syntax again:
[...state.shoppingCart, ...new Array(state.booksNumber).fill({...action.book})]
That will spread the new array into the existing array.
You can use the concat method
const a = new Array([1,3,4]).concat([1,3,4])
console.log(a)
This will add the elements into the array.
Or you can try with spread operator.
const arr=[1,2,3,4]
const a = new Array([1,3,4,.... arr]);
console.log(a)
You are missing the spread operator inside the returning array for the new Array you created.
Adding the spread operator allows you to merge/concat both array items.
For example:
const arrayOne = [1,2,3];
const arrayTwo = [4,5,6];
const mergedArrays = [...arrayOne, ...arrayTwo] //[1,2,3,4,5,6]
Also assuming action.book is an object you want to add multiple times inside of the new Array() you've created, there is no need to spread it as it will fill the array with each object.
This function might help out with what you are looking for:
const addMultipleItems = (action) => {
const items = new Array(state.booksNumber).fill(action.book);
return [...state.shoppingCart, ...items];
}
Why chaining function on array.flat not working as expected
const input = [[[{"type":"banana"},{"type":"orange"}]]];
console.log(input.flat(2).push({"type":"grapes"}));
What I expect is, it should remove the 2 array wrapper and push a new item to input
But I get only the length why is that ?
Array#push returns the new length of the array.
You could concat the array (Array#concat) with a new element and get the new array.
console.log(input.flat(2).concat({ type: "grapes" }));
Array.push mutates the array itself and returns only the length of the array. You can log the array in the next line after the push statement.
The push method returns the new length of the array and mutates it.
Try instead:
const input = [[[{"type":"banana"},{"type":"orange"}]]];
const flattened = input.flat(2)
flattened.push({"type":"grapes"});
console.log(flattened)
/*
[
{type:"banana"},
{type:"orange"},
{type:"grapes"}
]
*/
You can also other than Array.concat also spread into a new array to achieve the same result:
const input = [[[{"type":"banana"},{"type":"orange"}]]];
console.log([...input.flat(2), {"type":"grapes"}]);
The issue in your code however is that Array.flat returns a whole new array for you to work with and Array.push simply returns the new length of the array (so you need to keep a reference to the array). So with some refactoring:
const input = [[[{"type":"banana"},{"type":"orange"}]]];
let newArr = input.flat(2) // <-- this would return a new array
newArr.push({"type":"grapes"}) // We do not care what push returns since we have a reference to the array
console.log(newArr)
You get the expected result
Also note of caution with Array.flatMap and Array.flat ... both do not have support in IE and you would need a polyfill
I have 3 separate arrays and I'm looking to load them all into to a single array. Am I able to use .push() several arrays into one? Is something like this possible?
var activeMembers=[]; // Active Users
var noactiveMsg=[]; // Non-Active Users with a Pending Message
var noactiveNomsg=[]; // Non-Active Users without a Pending Message
var chatCenterMembers=[]; // Final Array of Chat Center Members
chatCenterMembers.push(activeMembers).push(noactiveMsg).push(noactiveNomsg);
Is there a way to chain .push()?
You're looking for the (vanilla) JavaScript method Array.concat().
Returns a new array comprised of this array joined with other array(s) and/or value(s).
Example, following your code:
chatCenterMembers = chatCenterMembers
.concat(activeMembers)
.concat(noactiveMsg)
.concat(noactiveNomsg);
chatCenterMembers.push(activeMembers,noactiveMsg,noactiveNomsg)
This question is quite confusing. First of all, the question seems to be asking for a way to combine multiple arrays into one single array containing the elements of all the arrays. However, the accepted answer provides a solution for creating an array of arrays. Since the text in the question suggests merging the elements of multiple arrays into one array while the code example uses push with arrays as arguments, it's quite ambigious what the OP wants.
Furthermore, several answers have suggested using concat. While that fulfills the requirement of returning the resulting array after adding the provided element, and is fine for small sets of data and/or where performance and memory is not an issue, it's inefficient if dealing with large arrays, since each concat operation will allocate a new array, copy all the elements of the old array into it, then copy all the elements of the provided array into it, and dereference the old array (as opposed to simply adding elements to the same array object).
Consider calling concat N times, adding C elements each time:
allocate new array, copy C elements
allocate new array, copy 2 * C elements
allocate new array, copy 3 * C elements
...
A different approach would be to create your own method, either as a separate function or adding it to the Array prototype:
Array.prototype.append = function(e) {
this.push(e);
return this;
}
With this, you could do
[1, 2, 3].append(4).append(5).append(6)
without allocating more than one array object in total.
It could perhaps also be mentioned that with ES2015, the spread operator can be used to add all the elements of an array to another array using push:
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
arr1.push(...arr2); // arr1 is now [1, 2, 3, 4, 5, 6]
This will however not fulfill the requirement of returning the resulting array for chaining, but the append method above could be used to merge multiple arrays like this:
chatCenterMembers = activeMembers.append(...noactiveMsg).append(...noactiveNomsg);
You can do it instead with .concat().
var chatCenterMembers=[];
chatCenterMembers = chatCenterMembers.concat(activeMembers, noactiveMsg, noactiveNomsg);
Since on one else has posted it:
var chatCenterMembers = activeMembers.concat(noactiveMsg, noactiveNomsg);
push AND unshift chaining
I actually came here looking for both but didn't see any good answer so far for unshift so I'll note that here as well.
push chaining is straight forward
const list = ['hi', 'there']
.concat(['buddy'])
// list is now ['hi', 'there', 'buddy']
but unshift chaining is weird
// need to use concat + map to do unshift chaining
const list = ['hi', 'there']
.concat(['buddy'])
.map((e, i, a) => i == 0 ? a[a.length - 1] : a[i-1])
// list is now ['buddy', 'hi', 'there']
As you can see using map there is a 3rd param given for the array you are using so this gives you power to do all sorts of odd things.