Nighthawk
Nighthawk

Reputation: 29

How can I delete falsy elements in an Object?

I am trying to delete the property funky: false from this object and return the other properties. Here is the code I have but for some reason it won't delete the item I need to delete.

var user = {
    name: "ernest",
    age: 50,
    funky: false
}

function truthyObjLoop(user) {
    for (prop in user) {
        if (prop === false) {
            delete(prop);
        } else {
            return (user);
        }
    }
}

Upvotes: 2

Views: 84

Answers (3)

thefourtheye
thefourtheye

Reputation: 239643

Actual problems

  1. delete is a statement and not a function. So, you don't have to use () with that.

  2. The delete statement removes a property from the object. When you do delete(prop), it will have no effect. Quoting MDN,

    delete is only effective on an object's properties. It has no effect on variable or function names.

Solution

So, as shown in the syntax section of MDN's delete page,

delete object.property
delete object['property']

to delete the object's property withe the variable prop, you should use the second form

delete user[prop];

Bugs in your code

Apart from that, your code has two bugs.

  1. You are returning immediately, if the current property's value is not false. You should iterate all the properties and then only you have to return.

  2. You should actually check the value of prop, not the prop itself.

  3. Make sure that you are declaring your loop variables. Otherwise they will become global properties.

So, your fixed code would look like this

function truthyObjLoop(user) {
    // Note: we use `var prop`, otherwise `prop` will become a global variable.
    for (var prop in user) {

        // This condition is to prevent removing inherited properties
        if (user.hasOwnProperty(prop) === false) {
            continue;
        }

        if (user[prop] === false) {
            delete user[prop];
        }
    }
}

truthyObjLoop(user);

console.log(user);
// { name: 'ernest', age: 50 }

Better way to do - avoid mutation

Now we are changing (mutating) the current object passed. But, the better alternate would be to construct a new object, without the properties you don't want, like this

function truthyObjLoop(user) {
    var result = {};
    for (var prop in user) {
        if (user.hasOwnProperty(prop) === false) {
            continue;
        }
        if (user[prop] !== false) {
            result[prop] = user[prop];
        }
    }
    return result;
}

console.log(truthyObjLoop(user));
// { name: 'ernest', age: 50 }
console.log(user);
// { name: 'ernest', age: 50, funky: false }

Upvotes: 4

Barmar
Barmar

Reputation: 782148

When you use for-in, the iteration variable is set to the property name, not the value (it's not like PHP foreach). You need to use user[prop] to get the value. Also, you should return after the entire loop -- you're returning as soon as you find a truthy property.

function truthyObjLoop(user) {
    for (prop in user) {
        if (user[prop] === false) {
            delete user[prop];
        }
    }
    return user;
}

Upvotes: 1

knolleary
knolleary

Reputation: 10117

prop is just the name of the property. To delete it from the object you need to do:

delete user[prop];

You also need to move your return statement outside of the for loop, otherwise it will return as soon as it sees the first non-false property and not check the others.

Upvotes: 2

Related Questions