1

I have an array of colors. I want to remove one which is equal to another object.

Array

[
    { id: 1, color: "red"},
    { id: 2, color: "blue"},
]

Object

{ id: 2, color: "blue" }

I do not know the index in the array. Ideally, it could be something like array.remove(object).

How can I achieve this?

Pixark
  • 385
  • 1
  • 3
  • 13

3 Answers3

3

Assuming "equal" means "having the same id", you just need a loop and an if test:

function removeItem(array, item) {
    for (var i = array.length - 1; i >= 0; i--)
        if (array[i].id === item.id) {
            array.splice(i, 1);
            break; // remove this line if there could be multiple matching elements
        }
}

var array = [
        { id: 1, color: "red"},
        { id: 2, color: "blue"},
    ];
removeItem(array, { id: 2, color : "blue"});

Obviously you can extend this to test both properties:

        if (array[i].id === item.id && array[i].color === item.color) {

If you wanted to be able to compare arbitrary objects with unknown property names then instead of a simple if test you could use a nested for..in loop to test each property, or perhaps something like this (untested):

function equalObjects(o1, o2) {
    var okeys1 = Object.keys(o1);
    if (okeys1.length != Object.keys(o2).length)
        return false;
    for (var i = 0; i < okeys1.length; i++)
        if (o1[okeys1[i]] !== o2[okeys1[i]])
            return false;
    return true;
}

and then in my original function:

         if (equalObjects(array[i], item)) {
nnnnnn
  • 138,378
  • 23
  • 180
  • 229
  • He will also be able to get the `array.remove(object)` syntax he wants by adding a similar function to `Array.prototype`. – Matt Nov 28 '13 at 14:49
  • @Matt - True. I'm not keen on modifying the prototype of built-in objects, so I'll leave that as an exercise for the reader... – nnnnnn Nov 28 '13 at 15:05
  • I agree with you there... I was mainly leaving it as a hint the OP ;). – Matt Nov 28 '13 at 15:46
2

I've made a mistake with this indexOf solution, but I'm correcting myself now:

function indexOf(arr, val, comparer) {
    for (var i = 0, len = arr.length; i < len; ++i) {
        if ( i in arr && comparer(arr[i], val) ) {
            return i;
        }
    }
    return -1;
}

var index = indexOf(array,someObject, function(o1,o2) { return o1.id == o2.id && o1.color == o2.color; });
if (index > -1) {
    array.splice(index, 1);
}

Fiddle: http://jsfiddle.net/AtGnY/5/

If you want to have it called this way: array.remove(object) then you can write this code like this:

Array.prototype.remove = function (object, comparer) {
    if (!comparer) {
        comparer = function (o1, o2) {
            return o1 === o2;
        };
    }
    var index = -1;
    for (var i = 0, len = this.length; i < len; ++i) {
        if (i in this && comparer(this[i], object)) {
            index = i;
        }
    }

    if (index > -1) {
        array.splice(index, 1);
    }
};

array.remove(object, function (o1, o2) {
    return o1.id == o2.id && o1.color == o2.color;
});

Fiddle: http://jsfiddle.net/AtGnY/14/

Kelu Thatsall
  • 2,307
  • 1
  • 17
  • 45
  • 2
    This will not work. He has an array of objects, not of colours. – Matt Nov 28 '13 at 14:44
  • indexOf() will not take an object as a parameter, this must be a string so you'd have to put this through a loop first. – Deryck Nov 28 '13 at 14:44
  • 1
    @Deryck - `.indexOf()` _will_ take an object, but this still won't work because `.indexOf()` uses strict equality so it would only remove the same _instance,_ not a duplicate object with properties set to the same values. – nnnnnn Nov 28 '13 at 14:45
  • Mmm, this will still not work. The objects wont be `==` (let alone `===`) just because their keys hold the same values. – Matt Nov 28 '13 at 14:45
  • @nnnnnn haha good to know guess I needa find some more reputable sites to get this from – Deryck Nov 28 '13 at 14:54
  • I've corrected my answer, you were right about standard indexOf, so I've found a solution with comparer. – Kelu Thatsall Nov 28 '13 at 14:56
  • 1
    @Deryck - MDN is pretty good. Just google "[any JS term here] mdn" and you'll be set. – nnnnnn Nov 28 '13 at 15:08
0

Similar question

That will at least give you access to the brute force method to solve your problem. Loop through the array and then compare each object.

Find an object by ID is more compact and elegant, but may not match your needs.

Community
  • 1
  • 1
Leo
  • 1,355
  • 22
  • 38