I have array of objects, that I get by array.filter. Now I want to make .map() function on this array and change specific object property in all objects in this array. Something like this
.map(task => task.description = task.description.replace(...);
But this gives me array of strings, not array of objects with this updated property. How to make this returning whole objects with just description updated?
Avoid to use "=" after arrow function if you do not explicite the return value
Try this :
const test = tasks.map(task => {
task.description = task.description.replace(...)
return task
});
console.log(test)
remember that, once you've .filter followed by .map, better to use .reduce() otherwise you'll loop twice on the same array.
Related
useEffect(() => {
cat &&
setFilteredProducts(
products.filter((item) =>
Object.entries(filters).every(([key, value]) =>
item[key].includes(value)
)
)
);
}, [products, cat, filters]);
I've been watching the video, over and over again but I can't seem to understand it properly, can somebody help me explain this line by line? I've get the point about "cat &&" but the rest confuses me.
Going through the above code line by line:
I am assuming you have a state variable with a setter function setFilteredProducts and two arrays products and filters, each having objects as values.
We are setting values in the state variable from the filtered values stored in the products variable.
Object.entries simply returns an array, where each item is an array with its first value as keys and the second value as the corresponding value, every is another function that applies on the array returned by the Object.entries function
The every function takes in a callback function as an argument, which tests whether all elements in the array pass the test implemented by the callback.
In this case, the test implemented is item[key].includes(value), which tests whether each iterated element(an object) in the products array has an array corresponding to key with value in it.
You can refer to
Object.entries here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
Array.prototype.every: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
Array.prototype.filter: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
Array.prototype.includes: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
you most your productlist.js check .i think there is a problem .when you have handleFilters check your value
Array.prototype.sort() method changes the array, so the value of the variable that refers to it is changed as well. It looks horrible to me, and I am unable to access the original array afterwards.
For example:
function keepOriginalArray([...arr]){
let storeWithoutSorting = arr; // I want original copy of array in variable.
arr.sort()
return storeWithoutSorting // gives result ['a','b'] . Variable's value was changed after calling sort method.
}
keepOriginalArray(['b', 'a'])
I am curious to know how does it work and how can I store a copy of the original array in a variable in this situation?
Sort mutates original array so you need to create a copy of array. here i am using ... spread syntax to create a shallow copy of original array
function keepOriginalArray(arr){
let storeWithoutSorting = [...arr];
arr.sort()
return storeWithoutSorting
}
console.log(keepOriginalArray(['b', 'a']))
Array is reference type. When you are storing arr value to storeWithoutSorting , you are actually storing its reference. Thats why both are getting sorted when you are performing the sort.
To create a copy of an array, you can use spread operator:
let storeWithoutSorting = [...arr]
It will create a new array with new reference. Hence it won't be manipulated when you perform sort on arr.
I'm solving a problem where the task is to merge multiple objects from the input array and return a single object with all the keys and values merged. In case a key exists in one or more objects in the input array, the most recent value for that key should be stored in the final returned object.
An example -
var a={1:'1',2:'2',3:'3'},
b={3:'4',5:'6',6:'7',7:'8'},
c={5:'9',8:'9',6:'12',23:'35'}
o=[a,b,c];
The returned object should be -
{ '1': '1','2': '2','3': '4','5': '9','6': '12','7': '8','8': '9','23':'35' }
As an example of the duplicate key case, key 3 exists in both objects a and b, so in the final result the value is {3:'4'} because that is the most recent.
I want to use the spread syntax for Objects in this problem, but that solves only a part of it. What I mean is, if I use spread for each object individually, that works, like -
function foo() {
var a={'1':'1','2':'2','3':'3'},
b={'3':'4','5':'6','6':'7','7':'8'},
c={'5':'9','8':'9','6':'12','23':'35'},
arr = [a,b,c];
return {...arr[0], ...arr[1], ...arr[2]}
}
console.log(foo());
For this to work, I need to write out each array element with spread, as in the above snippet - ...arr[0], ...arr[1], ...arr[2]. However, the input array can contain any number of objects, so writing out each element is not feasible.
Normally, using spread on an iterable like an array, allows you to expand the array elements, like so-
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
console.log(lyrics)
Is it possible to use spread on the input array to collect all the individual objects, on which spread can be applied again, to get the final object?
You could just use Object.assign():
return Object.assign(...arr);
Here's a complete snippet:
function foo() {
var a={'1':'1','2':'2','3':'3'},
b={'3':'4','5':'6','6':'7','7':'8'},
c={'5':'9','8':'9','6':'12','23':'35'},
arr = [a,b,c];
return Object.assign(...arr);
}
console.log(foo());
Note that this implicitly modifies the first object in your array. If you don't want that, pass a new empty object as the first argument to Object.assign():
return Object.assign({}, ...arr);
You can directly use spread syntax on object to merge them.
function foo() {
var a={'1':'1','2':'2','3':'3'},
b={'3':'4','5':'6','6':'7','7':'8'},
c={'5':'9','8':'9','6':'12','23':'35'};
return {...a, ...b, ...c};
}
console.log(foo());
If you have an array, then you can use array#reduce and Object#assign.
var a={'1':'1','2':'2','3':'3'},
b={'3':'4','5':'6','6':'7','7':'8'},
c={'5':'9','8':'9','6':'12','23':'35'},
arr = [a,b,c];
var result = arr.reduce(function(r,o){
return Object.assign(r,o);
},Object.create(null));
console.log(result);
NOTE : The Rest/Spread Properties for ECMAScript proposal (stage 3) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object.
I have an array of objects as follows:
var myarray=[{"name":"John","address":"home"},{"name":"Peter","address":"home"}]
and I would like to run a function to add a property to the array as follows:
[{"name":"John","address":"home","collection":"friend"},
{"name":"Peter","address":"home","collection":"friend"}]
I have tried doing this:
myarray=myarray.map(function (err, myarray){
myarray.collection="friend";
return myarray;
}
console.log(myarray)
But the console continues to return this:
[{0},{1}]
Can anyone help me? Thank you
Your code is not adding the property to the contents of the array. The values of the array are given as the first parameter to the callback function (the second parameter is an index, and not the array itself—that's the third parameter). Simply assign the new property to the first parameter of the callback function, rather than the second one.
Edit - As #zerkms points out, however, if you're looking to update the current array rather than generate a new array, map is probably not best solution here. forEach provides a method for iterating over the current array, and modifying each of its values (which is what you're doing). This would looks omething like this:
myarray.forEach(function(value) {
value.collection = "friend";
});
As you'll notice in the documentation for .map, the callback function returns the new value that will appear in the new array that is generated by map; if you're changing the current array in place (i.e. by modifying the properties of its contents), there's no need to return anything.
myarray.map(function(value) {
value.collection = "friend";
});
Also note that both map and forEach are methods, so you need to close the method invocation with ).
Wrong use of map().
The first argument of map() is the current element of the array, the second argument is it's index.
For example:
['a','b','c'].map(function(element, index){console.log(element, index)});
Will result in
a 1
b 2
c 3
So inside your function myarray was your index, and you were trying to add the property to the index.
Now you have to options. Either you use the map() as it's ment to be used and assign it's return value to myarray:
myarray = myarray.map(function(element) {
element.collection = "friend";
return element;
});
or you can, because objects are not getting copied but referenced when passed as an argument, not care about the return values and modify the elements directly:
myarray.map(function(element) {
element.collection = "friend";
}); // returns [undefined, undefined ...]
This, however, isn't the way one should use map()
Better: Use forEach()
myarray.forEach(function(element) {
element.collection = "friend";
});
Hope it helped.
Greets!
All you have to do is changing the reference object within map function
myarray.map(function (value){
value.collection = "friend";
});
console.log(myarray);
I've found something interesting and I don't know why it's happening.
If I try in google chrome developer tools, the following two staments
(Array([1,2,3])).filter(function (item, index, array) {
return item === 1;
}); ==> []
and
([1,2,3]).filter(function (item, index, array) {
return item === 1;
}); ==> [1]
The results are an empty array for the first statement and array with a single value (1) for the second
Inspecting the parameters for the callback function, i found that in the first statement the arguments are (array, index, value) and for the second statemente are(value, index, array).
Inspecting with typeof and constructor of both objects the result are the expected, and the same "object", and Array.
Why is this happening?
Thanks
Because that's not how you define an array with Array().
Should be without the square brackets, otherwise it's an array of a single element, which is also an array ([1,2,3]).
Array(1,2,3)
That inner array never equals to 1 (basically you check [1,2,3] == 1), so the result is an empty array.
If you define an array by using Array([1,2,3]) this code, then the following array will be created,
[[1,2,3]]
Since you are pushing an array into another one. And if you really want the Array function to create an array by reading an array then you have to write something like this,
Array.apply([], [1,2,3])
But the above one is completely pointless. Again I am telling it is completely pointless since we are having an array that we require in our hand. But just for a knowledge you can know about it.
Array([1,2,3]) create array of arrays [[1, 2, 3]] so .map()function will iterate one time only.
If you want to create array with Array constructor use next syntax:
Array(1,2,3)
the shorter is the better :
[1,2,3].filter(item => item === 1);