Select a property from an array of objects based on a value : Javascript
Solution 1
You can use reduce
and check if the checked
property is true, then push
(As pointed out by assoron) the value to the accumulator - there is no need for 2 loops:
const arr = [
{ "value": "abc", "checked": true },
{ "value": "xyz", "checked": false },
{ "value": "lmn", "checked": true }
]
const filtered = arr.reduce((a, o) => (o.checked && a.push(o.value), a), [])
console.log(filtered)
Solution 2
use filter and map:
const arr =[{"value":"abc","checked":true},{"value":"xyz","checked":false},{"value":"lmn","checked":true}];
const result = arr.filter(res=>res.checked).map(ele=>ele.value);
console.log(result);
Solution 3
Firstly, that's not valid JS - you need to swap your brackets and braces. Arrays use []
, and objects use {}
, not the other way around.
Secondly, you should first filter
out the wanted objects based on the checked
property, then use map
to extract the properties you want:
const arr =[{"value":"abc","checked":true},{"value":"xyz","checked":false},{"value":"lmn","checked":true}];
const res = arr.filter(({ checked }) => checked).map(({ value }) => value);
console.log(res);
Solution 4
You can use .reduce
to essentially map
and filter
at the same time. Below I have built an accumulated array using [v].slice(+!c)
which will add the value to the (accumulated) array if c
is true, else, it will not add it to the array (as [v].slice(+!false)
will return []
, and [...[]]
will give []
):
const arr = [{
"value": "abc",
"checked": true
}, {
"value": "xyz",
"checked": false
}, {
"value": "lmn",
"checked": true
}];
const res = arr.reduce((a, {value:v, checked:c}) => [...a, ...[v].slice(+!c)], []);
console.log(res);
Solution 5
Array.prototype.reduce()
might help you. reduce()
callback takes two arguments, who's first argument is the old/previous iteration value and second argument is the current iteration value/element.
So using this function we can holds our current iteration values to the previous iteration value (total values).
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.
var arr = [{"value": "abc","checked": true},{"value": "xyz","checked": false},{"value": "lmn","checked": true}]
const result = arr.reduce((acc, cur) => ((cur.checked && acc.push(cur.value)), acc), [])
console.log(result)
Related videos on Youtube
joy08
Updated on June 09, 2020Comments
-
joy08 almost 4 years
I have an array of objects with the following structure:
var arr = [ { "value": "abc", "checked": true }, { "value": "xyz", "checked": false }, { "value": "lmn", "checked": true } ]; let result = arr.filter(item => item.checked); console.log(result);
I would want the output to be:
["abc", "lmn"]
Because those two
value
s havechecked: true
.I have tried filtering out based on checked value:
let result = arr.filter(item => item.checked);
I am getting the objects that has
checked
property value that is set totrue
.Help would be appreciated.
-
CertainPerformance almost 5 yearsYour input's syntax is invalid. Consider providing a valid data structure. Arrays do not have key-value pairs, only values
-
Matsemann almost 5 yearsPossible duplicate of use filter to return property values in an object
-
-
MH2K9 almost 5 yearsonly returns the last one of (...)
-
Kobe almost 5 yearsThats why I used reduce :) Nonetheless, a for loop is more efficient here.
-
Rajaprabhu Aravindasamy almost 5 years@Kobe Agree...!
-
claasic almost 5 yearsFaster than all the
filter
plusmap
answers for sure. But why useconcat
for this? Wouldn't{if (c.checked) {a.push(c.value) }; return a}
be more efficient? Spread syntax afaik is kinda slower so that might be a third but likely worse option anyway. -
Kobe almost 5 years@assoron Yes, you are right. I only wrote concat so you could write it on one line so as to be more readable. And spread syntax is horribly slower, I remember writing a JSPerf once and iirc it was 50% slower.
-
Kobe almost 5 years@assoron check this perf jsperf.com/push-vs-concat-with-reduce/1 - 94% slower lol
-
claasic almost 5 yearsMy ancient browser setup puts concat as 40% slower.
-
Jack Bashford almost 5 yearsYou can do it in one line with
push
:(a.push(o.value), a)
. -
Kobe almost 5 years@JackBashford I never knew this existed, thanks, that will help for a lot more one liners with efficiency too :P
-
Jack Bashford almost 5 yearsNo worries - I (ab)use the comma operator like that in a lot of my
reduce
answers now. -
Kobe almost 5 years@JackBashford Are you able to explain how it works?
-
Jack Bashford almost 5 yearsYep - the comma operator evaluates all code passed, then uses the last one. So
a.push(o.value)
is run, thena
is used as the return value of the expression, and returned from the function. Make sense? -
Kobe almost 5 yearsHow come you are using old syntax here? It looks odd on one line when it's not es6 :P
-
SK. almost 3 yearsif you want unique values: const result = Array.from(new Set(arr.filter(res=>res.checked).map(ele=>ele.value)));