chovy
chovy

Reputation: 75686

using _.reject turns my object into an array

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.

Upvotes: 3

Views: 4735

Answers (7)

tybro0103
tybro0103

Reputation: 49713

Use _.omit():

_.omit(data.stuff, function(val) { return val.disabled; });

See fiddle: https://jsfiddle.net/ehbmsb5k/

Upvotes: 1

Sacha
Sacha

Reputation: 2007

You could use _.omit() instead.

Upvotes: 5

chovy
chovy

Reputation: 75686

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];
    }
}

Upvotes: 1

Gruff Bunny
Gruff Bunny

Reputation: 27976

What @archie said but in code:

data.stuff = _.reduce(data.stuff, function(memo, value, key){
    if( !value.disabled) memo[key] = value;
    return memo;
}, {});

Upvotes: 4

thefourtheye
thefourtheye

Reputation: 239503

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

  1. _.pairs converts the {key:value} pairs into [key, value] array.

  2. _.filter filters the items whose disabled is a falsy value.

  3. _.object converts the filtered [key, value] array into {key:value} pairs.

Upvotes: 3

sergelerator
sergelerator

Reputation: 576

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 accomplish what you want:

_.each(Object.keys(data.stuff), function(val) {
    if (data.stuff[val].disabled)
        delete data.stuff[val];
});

Upvotes: -1

aarti
aarti

Reputation: 2865

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.

Upvotes: 0

Related Questions