8

Take, for instance, the following object:

var fruits = {
    "red" : "apple",
    "blue" : "blueberry",
    "yellow" : "banana"
}

I know I can use delete fruits["red"] to remove it by the key name, but how could I delete the object item by the fruit name?

2
  • stackoverflow.com/questions/9907419/… Commented Mar 28, 2012 at 15:05
  • i believe mdm's solution is the only way to achieve this functionality, i'm curious to see if anyone has something clever... Commented Mar 28, 2012 at 15:06

9 Answers 9

10

Have you tried something like this?

function deleteByValue(val) {
    for(var f in fruits) {
        if(fruits[f] == val) {
            delete fruits[f];
        }
    }
}

And as per Rocket's comment, you might want to check hasOwnProperty to make sure you aren't deleting members of the object's prototype:

function deleteByValue(val) {
    for(var f in fruits) {
        if(fruits.hasOwnProperty(f) && fruits[f] == val) {
            delete fruits[f];
        }
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Is JS not that picky about deleting an item while in the middle of an iterator? (I may just be playing it extra safe, but didn't know if you had an absolute answer).
Shouldn't you check for hasOwnProperty inside the for...in?
You should skip the rest of the loop if you found a key, because it won't appear a second time.
You're deleting by value, not key, and a value could easily appear twice. A key is guaranteed to only appear once.
Oh, that's true. My bad. Sorry!
|
1
var key = null;
for (var k in fruits){
  if (fruits[k] === 'apple'){
    key = k;
    break;
  }
}
if (key != null)
  delete fruits[key];

Iterate over the object finding the corresponding key, then remove it (if found).

1 Comment

Shouldn't you check for hasOwnProperty inside the for...in?
1

Don't know if this is efficient in terms of processing but using filter you can get this done in three lines:

var fruits = {
    "red" : "apple",
    "blue" : "blueberry",
    "yellow" : "banana"
}

var appleless_keys = Object.keys(fruits).filter(this_fruit => fruits[this_fruit] !== "apple");
appleless_obj = {};
appleless_keys.forEach(key => appleless_obj[key] = fruits[key]);
console.dir(appleless_obj);

Or as a function:

var fruits = {
    "red" : "apple",
    "blue" : "blueberry",
    "yellow" : "banana"
}

function remove_fruit(fruit_to_remove,fruits){
  var new_keys = Object.keys(fruits).filter(this_fruit => fruits[this_fruit] !== fruit_to_remove);
  new_obj = {};
  new_keys.forEach(key => new_obj[key] = fruits[key]);  
  return new_obj;
}

console.dir(remove_fruit("apple",fruits));

Comments

1

Simplified using key deletion,

function stripProperty(o, v) {
    return  (delete o[Object.keys(o).splice(Object.values(o).indexOf(v), 1)])?o:0;
}   

    var fruits = {
        "red" : "apple",
        "blue" : "blueberry",
        "yellow" : "banana"
    }

    function stripProperty(o, v) {
        return  (delete o[Object.keys(o).splice(Object.values(o).indexOf(v), 1)])?o:0;
    }   


    console.log(stripProperty(fruits, 'banana'));

Usage,

var fruits = {
    "red" : "apple",
    "blue" : "blueberry",
    "yellow" : "banana"
}

console.log(stripProperty(fruits, 'apple'))

Comments

0

what about this one?

function delteByValue(a){
  fruits.foreach( function( k, v ) {
    if (fruits[v] == a){
      delete fruits[k];
    }
  });
}

Comments

0

I think its a good idea to create a function and override the Object.prototype:

/**
 *  @autor Javier Cobos
 *  @param value The value to look for
 *  @return true if founded deleted, false if not
 */        
Object.prototype.removeByValue = function(value){
         var i;
         for(i in this){
            if(this.hasOwnProperty(i))
                if(value === this[i]){
                   delete(this[i]);
                   return true;
                }
         }   
         return false;
        }

// Example
     var fruits = {
        "red" : "apple",
        "blue" : "blueberry",
        "yellow" : "banana"
    }

        fruits .removeByValue("apple");

This way we have a new method for every single Object in our script :)

2 Comments

Extending Object.prototype and Array.prototype create a lot of surface issues in IE<=8 ... Best to add such a method to a utility such as Underscore or jQuery. $.removeByValue = function(object, value) { ... } (note: these problems tend to present themselves dealing with 3rd party scripts, such as google analytics or ads)
Maybe you can encapsulate this functionality into the function you are using it to avoid conflicts
0

I know you have several acceptable answers at this point... I'm going to include a generic function for this...

// NOTE, replace "Object.removePropertyByValue" 
// with say "jQuery.removePropertyByValue" or "_.removePropertyByValue"
// to create a jQuery or Underscore extension.
Object.removePropertyByValue = function(obj, val) {
  //store list of properties to remove
  var propsToRemove = [];

  for (var prop in obj) {
    if (obj.hasOwnProperty(prop) && obj[prop] === val) {
      //save the property name here, deleting while enumerating is a bad idea.
      propsToRemove.push(prop);
    }
  }

  //remove all the items stored.
  while (propsToRemove.length) delete obj[propsToRemove.pop()];
}

From here you should be able to call: Object.removePropertyByValue(fruits, "red");

1 Comment

It's safe to bind a method to the Object constructor, but not safe to extend the Object.prototype (or Array.prototype), as there are a lot of unintended consequences in third party scripts. (looking at you Google)
0

use this function

function delobj(obj,val){
    for (x in obj) {
        if(obj[x] == val)
        delete obj[x]
    }
    return obj;
}

use like this

delobj(object "object name",string "value of element")

1 Comment

Uncaught TypeError: x.filter is not a function?
-1

You can use the splice method

fruits.splice($.inArray("red", fruits), 1);

But this uses jQuery of course.

You can also use this extension:

Array.prototype.remove = function () {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
        what = a[--L];
        while ((ax = this.indexOf(what)) != -1) {
            this.splice(ax, 1);
        }
    }
    return this;
}

1 Comment

It's an object, not an array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.