I have some data that I want to iterate through and reject those with a disabled: true
property.
however when I try _.reject
my object gets turned into an array.
var data = {
stuff: {
item1: {
name: "one",
disabled: true
},
item2: {
name: "two"
}
}
};
data.stuff = _.reject(data.stuff, function(val){
return val.disabled;
});
data.stuff
is now an array, rather than an Object. I've lost all my keys.
I have some data that I want to iterate through and reject those with a disabled: true
property.
however when I try _.reject
my object gets turned into an array.
var data = {
stuff: {
item1: {
name: "one",
disabled: true
},
item2: {
name: "two"
}
}
};
data.stuff = _.reject(data.stuff, function(val){
return val.disabled;
});
data.stuff
is now an array, rather than an Object. I've lost all my keys.
-
1
_.reject
can only return an array. – user229044 ♦ Commented Jan 5, 2014 at 7:50 -
1
Semantically, your
stuff
actually even should be an array. Really.item1
,item2
either is useful data (then turn it into anid
property, respectively) or it isn't (then drop it). – Tomalak Commented Jan 5, 2014 at 8:29
7 Answers
Reset to default 5You could use _.omit()
instead.
What @archie said but in code:
data.stuff = _.reduce(data.stuff, function(memo, value, key){
if( !value.disabled) memo[key] = value;
return memo;
}, {});
When you pass data.stuff
(which is an Object) to _.reject
, it picks only the values of the object and passes that to _.reject
. So, key
information is lost and reconstructing the object is not possible.
Instead, you can do it like this
data.stuff = _.object(_.filter(_.pairs(data.stuff), function(list) {
return list[1].disabled;
}));
console.log(data);
Output
{ stuff: { item1: { name: 'one', disabled: true } } }
How it works
_.pairs
converts the{key:value}
pairs into[key, value]
array._.filter
filters the items whosedisabled
is a falsy value._.object
converts the filtered[key, value]
array into{key:value}
pairs.
I ended up just using native javascript instead of underscore:
//remove disabled items
for ( var item in data.stuff ) {
if ( data.stuff[item].disabled ) {
delete data.stuff[item];
}
}
Use _.omit()
:
_.omit(data.stuff, function(val) { return val.disabled; });
See fiddle: https://jsfiddle/ehbmsb5k/
Have you looked at doing this with _reduce, where the memo is a new hash, in which you merge the items( key, value pair) you need.
The original data.stuff
is not changed when you use reject
. But since you are assigning to the stuff
key, the original data is lost.
_.reject
is supposed to work on and return arrays. You could try this in order to acplish what you want:
_.each(Object.keys(data.stuff), function(val) {
if (data.stuff[val].disabled)
delete data.stuff[val];
});