I'm confused about this statement, Object.entries - javascript

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

Related

Update all objects property value in array

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.

How the order of arguments works in a reduce helper method?

// this is the array
var numbers = [10,20,30];
// Now I want to get the sum of all the elements of numbers array
// this will give 60
numbers.reduce(function(sum,number){
return sum + number;
},0);
// this also gives 60
numbers.reduce(function(number,sum){
return sum + number;
},0);
I am just learning ES6, I tried looking at MDN but couldn't find the explanation. I just want to know how javascript detects the argument with initial value to be zero and which it detects to be the array elements.
Or does it arbitrarily chooses the argument values.
According to MDN, the first argument will always be the sum/accumulator, and the second will be the value.
Both parameters have no inherit binding to a name, so you can name both the sum and the value whatever you wish.
In your example, the first one works probably as you expected, with the sum as the first parameter and the value as the second parameter. In your second example, it works the exact same way, the only difference being that you named the 'sum' as 'number' and the 'value' as 'sum'.
JS may be weird but it's not messing with your arguments in this case. You're just naming the arguments differently.
From MDN:
The first time the callback is called, accumulator and currentValue
can be one of two values. If initialValue is provided in the call to
reduce, then accumulator will be equal to initialValue, and
currentValue will be equal to the first value in the array. If no
initialValue is provided, then accumulator will be equal to the first
value in the array, and currentValue will be equal to the second.
Note: If initialValue isn't provided, reduce will execute the callback
function starting at index 1, skipping the first index. If
initialValue is provided, it will start at index 0.
The first param, "sum", is the accumulator. The second param, currentValue, is "number".
Here's the syntax of the reduce method.
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
where, function is used to reduce the array and will be invoked for each array element.
This function uses first argument passed to it as an accumulator to store the result.
Each element of the array will be passed as the second argument to the function.
Just like other functions in JavaScript, the order of the parameters matter(not their name).
While these two parameters are required to be present in your function, it can have two more optional parameters, viz currentIndex and the array itself.
And finally, the optional initValue passes to reduce function will be used to initialize the accumulator.
You can read more about it here.

Using destructuring assignment and the rest syntax for default variables

The following is an attempt to set the default value for an argument, based on the first argument:
function tree(values, ...[[curr] = values]) {
console.log(curr);
}
tree(['foo']); // foo
tree(['foo'], ['bar']); // bar
It appears to work (actually it isn't quite what I want, but I want to understand this first).
What is going on here?
The spread syntax is spreading an anonymous array with the contents of curr…
No. Nothing is being spreaded into an array literal.
The spread syntax is capturing the rest of the arguments into an anonymous array instance which is being destructured…
Yes.
…into the first value of either: the supplied array if present, or values.
Not sure I understand. The captured array is destructured to the target [[curr] = values], which takes out the first element or - if not present - the values default, and assigns that to the target [curr].
And as #FelixKling commented, you really should not do that, but use
function tree(values, [curr] = values) {
console.log(curr);
}
This happens because default parameters can reference previous parameters. In your example you are destructuring values to curr, that's why the console is printing the first element of the array. You could suppress the spread operator and the result would be the same:
function tree(values, [curr] = values) {
console.log(curr);
}
tree(['foo']); // foo
tree(['foo'], ['bar']); // bar
What is happening to the second call tree(['foo'], ['bar']) is that the second argument (['bar']) is overriding [curr] default value.
Please let me know if I wasn't clear enough.
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters (look for the section titled "Default parameters are available to later default parameters")

Javascript: Adding a property to an array of objects

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);

Javascript array type casting

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);

Categories

Resources