I want to filter the object of booleans and then select the key name of the true item in the most efficient way, drawing a blank on selecting the active key name.
const winners = {
lg: false
md: true
sm: false
xs: false
}
const active = Object.entries(winners).filter(([key, bool]) => !!bool)[0][0]
//this seems quite ugly, can I chain active or flatten the list to get the key 'md'?
Maybe something like this:
const [key, value] = Object.entries(winners).filter(([key, bool]) => !!bool)[0]
I want to filter the object of booleans and then select the key name of the true item in the most efficient way, drawing a blank on selecting the active key name.
const winners = {
lg: false
md: true
sm: false
xs: false
}
const active = Object.entries(winners).filter(([key, bool]) => !!bool)[0][0]
//this seems quite ugly, can I chain active or flatten the list to get the key 'md'?
Maybe something like this:
const [key, value] = Object.entries(winners).filter(([key, bool]) => !!bool)[0]
Share
Improve this question
edited Aug 19, 2020 at 19:27
styler
asked Aug 19, 2020 at 19:12
stylerstyler
16.5k25 gold badges85 silver badges139 bronze badges
1
- Was messing around with the oute with some trial and error @trincot – styler Commented Aug 19, 2020 at 19:23
5 Answers
Reset to default 4You can use a for loop:
let winnerKey = null;
for(let key in winners) {
if(winners[key]) {
winnerKey = key;
break;
}
}
If you want a readable solution which gets all true keys, then
true_keys = Object.keys(winners).filter(key=>winners[key]);
isn't a bad choice.
If you want speed them @domenikk's answer is the way to go, but otherwise readability is usually preferable over maximum efficiency (I mean, you are using JS).
Can use pickBy
, with some sort of destructuring:
function pickBy(object) {
const obj = {};
for (const key in object) {
if (object[key]) {
obj[key] = object[key];
}
}
return obj;
}
const [key, value] = Object.entries(pickBy(winners))[0]
- https://github./you-dont-need/You-Dont-Need-Lodash-Underscore#_pickby
You could also use a reduce:
Object.entries(winners).reduce((p, [key, value]) => value ? key : p, null)
"md"
Object.entries({}).reduce((p, [key, value]) => value ? key : p, null)
null
I would use something like this:
const winners = {
lg: false,
md: true,
sm: false,
xs: false,
}
const active = Object.keys(winners).filter(key => winners[key])[0]
Do not you think that array of object is more suitable store for winners? Like
const winners = [
{
name: "lg",
is_winner: false
},
{
name: "md",
is_winner: true
},
...
]
That way you could easily manage the list of winners - add, delete, filter etc. To create that kind of storage you can use
const winnersArray = Object.keys(winners).map(key => ({ "name": key, "is_winner": winners[key] }))
You can stop iterating as soon as a true
is found.
const test = {
lg: false,
md: true,
sm: false,
xs: false
}
const winner = Object.keys(test)[Object.values(test).indexOf(true)]
console.log(winner)