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];
}
Related
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.
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 have an array which has thousands of rows from google spreadsheet for example:-
var array = [[1,2,3,4],[2,3,4,1],[1,4,5,6]......]
I want to add an element lets say "x" end of every array. I need a solution like this :-
[[1,2,3,4,x],[2,3,4,1,x],[1,4,5,6,x]......]
How can I achieve this.
#Askish has a great answer, but I would like to provide an alternative.
This approach mutates the arrays instead of creating new ones
var array = [[1,2,3,4],[2,3,4,1],[1,4,5,6]];
array.forEach(e => e.push("x"));
console.log(array);
var array = [[1,2,3,4],[2,3,4,1],[1,4,5,6]];
var newArray = array.map(x => [...x, 'x']);
console.log(newArray);
Lets say I have the following map:
let myMap = new Map().set('a', 1).set('b', 2);
And I want to obtain ['a', 'b'] based on the above. My current solution seems so long and horrible.
let myMap = new Map().set('a', 1).set('b', 2);
let keys = [];
for (let key of myMap)
keys.push(key);
console.log(keys);
There must be a better way, no?
Map.keys() returns a MapIterator object which can be converted to Array using Array.from:
let keys = Array.from( myMap.keys() );
// ["a", "b"]
EDIT: you can also convert iterable object to array using spread syntax
let keys =[ ...myMap.keys() ];
// ["a", "b"]
You can use the spread operator to convert Map.keys() iterator in an Array.
let myMap = new Map().set('a', 1).set('b', 2).set(983, true)
let keys = [...myMap.keys()]
console.log(keys)
OK, let's go a bit more comprehensive and start with what's Map for those who don't know this feature in JavaScript... MDN says:
The Map object holds key-value pairs and remembers the original
insertion order of the keys.
Any value (both objects and primitive
values) may be used as either a key or a value.
As you mentioned, you can easily create an instance of Map using new keyword...
In your case:
let myMap = new Map().set('a', 1).set('b', 2);
So let's see...
The way you mentioned is an OK way to do it, but yes, there are more concise ways to do that...
Map has many methods which you can use, like set() which you already used to assign the key values...
One of them is keys() which returns all the keys...
In your case, it will return:
MapIterator {"a", "b"}
and you easily convert them to an Array using ES6 ways, like spread operator...
const b = [...myMap.keys()];
I need something similiar with angular reactive form:
let myMap = new Map().set(0, {status: 'VALID'}).set(1, {status: 'INVALID'});
let mapToArray = Array.from(myMap.values());
let isValid = mapToArray.every(x => x.status === 'VALID');
Not exactly best answer to question but this trick new Array(...someMap) saved me couple of times when I need both key and value to generate needed array. For example when there is need to create react components from Map object based on both key and value values.
let map = new Map();
map.set("1", 1);
map.set("2", 2);
console.log(new Array(...map).map(pairs => pairs[0])); -> ["1", "2"]
Side note, if you are using a JavaScript object instead of a map, you can use Object.keys(object) which will return an array of the keys. Docs: link
Note that a JS object is different from a map and can't necessarily be used interchangeably!