-1

Let's say I have the following array:

var things = [
    {
        id: "12345",
        name: "Bryan"
    },
    {
        id: "55555",
        name: "Justin"
    }
]

I want to search for the object with the id of 55555. But I want to update the name of that particular object to "Mike" from Justin but still keep the entire army intact.

At the moment, I kinda figured out a way to search for the object, but I can't find a solution to actually edit that particular finding.

Could anyone help me out? This is what I have so far:

var thing = things.filter(function (item) {
    return "55555" === item.id;
})[0]
bryan
  • 8,879
  • 18
  • 83
  • 166

4 Answers4

1

How about a function that finds the correct ID and changes the name

var things = [
    {
        id: "12345",
        name: "Bryan"
    },
    {
        id: "55555",
        name: "Justin"
    }
]

function updateThings(id, value, arr) {
    arr.forEach(function(item) {
        if (item.id == id) {
           item.name = value;
           return false;
        }
    });
}

updateThings("55555", "Mike", things);

document.body.innerHTML = '<pre>' + JSON.stringify(things, null, 4) + '</pre>';
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • If I have to do let's say 100 different searches to an array thats very big, is there a better way to do this or is cycling through the best option? – bryan Apr 25 '15 at 16:15
  • @bryan You're pretty much always going to be cycling one way or another. Computers can cycle through thousands of entries incredibly quickly these days so I wouldn't worry about speed – Downgoat Apr 25 '15 at 16:19
  • If you had to a 100 searches, they are probably better ways, for instance iterating once and using a map to do the replacing. – adeneo Apr 25 '15 at 16:19
  • @adeneo that makes sense. Quick question, instead of editing the value, is there a simple solution for deleting that found "Thing"? – bryan Apr 25 '15 at 17:12
  • Sure, you can do `delete item.name` – adeneo Apr 25 '15 at 17:43
  • @adeneo what about deleting the whole `item`? I tried `delete item` and it didn't work – bryan Apr 25 '15 at 17:52
  • That's part of the outer array, and can't be deleted, you'd have to slice the array and overwrite it. – adeneo Apr 25 '15 at 18:01
1

I would just loop over the array, check if the ID matches and edit the name.

for (var i = 0; i < things.length; i++) {
    if (things[i].id == "55555") {
        things[i].name = "new name";
    }
}
Jeroen Noten
  • 3,574
  • 1
  • 17
  • 25
1

Using .filter() is inefficient since it keeps iterating after it finds the item you are looking for.


You could define a generic function like this:

function findElementByPropertyValue(arr, propertyName, propertyValue) {
    for (var i = 0, count = arr.length; i < count; i++) {
        var element = arr[i];
        if (element[propertyName] === propertyValue) {
            return element;
        }
    }
    return null;
}

And then use it like this:

var mike = findElementByPropertyValue(things, 'id', '55555');
if (mike) {
    mike.name = 'Mike';
}

jsfiddle


If you need to alter a lot of elements in the array, you may want to create a hash object instead.

function createHashByProperty(arr, propertyName) {
    var hash = {};
    for (var i = 0, count = arr.length; i < count; i++) {
        var element = arr[i];
        hash[element[propertyName]] = element;
    }
    return hash;
}

You can use it like this:

var hash = createHashByProperty(things, 'id');

hash['55555'].name = 'Mike'; // Was 'Justin'
hash['12345'].name = 'Brian'; // Was 'Bryan'

jsfiddle


The two functions above do not alter the array, they just allow you to get references to the elements in the array, so you can alter those elements.

If you want to remove an element from the array, you will need to get its index. You can then use the Array.prototype.splice function to remove the element.

Here is a function that does this:

function removeElementByPropertyValue(arr, propertyName, propertyValue) {
    for (var i = 0, count = arr.length; i < count; i++) {
        if (arr[i][propertyName] === propertyValue) {
            arr.splice(i, 1);
            return;
        }
    }
}

You can use it like this:

removeElementByPropertyValue(things, 'id', '55555');

jsfiddle


Note: The code in this answer uses plain JavaScript; It is not dependent on the jQuery library.

John S
  • 21,212
  • 8
  • 46
  • 56
0

To be efficient, you could store the locations of each item and then use that to reference the name:

var things = [
    {
        id: "12345",
        name: "Bryan"
    },
    {
        id: "55555",
        name: "Justin"
    }
], reference  = things.map(function(a){ return a.id });;

function replace (id, name, ar, ref) { ref.indexOf(id)>-1&&(ar[ref.indexOf(id)]['name']=name); }

replace("55555", "Phil", things, reference);

In this, you will only need to loop one time. Then all the information is stored in the reference variable. reference stores where the id is, which we use to avoid looping. I'm not sure what the compiler is doing and whether it loops or not but this just feels more efficient.

.indexOf isn't completely supported so you can use a PollyFill

Add this code to the top of the JavaScript file:

[].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b<c&&(!(b in this)||this[b]!==a);b++);return b^c?b:-1;})

and

Array.prototype.map||(Array.prototype.map=function(r,t){var n,o,e;if(null==this)throw new TypeError(" this is null or not defined");var i=Object(this),a=i.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(n=t),o=new Array(a),e=0;a>e;){var p,f;e in i&&(p=i[e],f=r.call(n,p,e,i),o[e]=f),e++}return o});

along with:

Array.prototype.forEach||(Array.prototype.forEach=function(r,t){var o,n;if(null==this)throw new TypeError(" this is null or not defined");var e=Object(this),i=e.length>>>0;if("function"!=typeof r)throw new TypeError(r+" is not a function");for(arguments.length>1&&(o=t),n=0;i>n;){var a;n in e&&(a=e[n],r.call(o,a,n,e)),n++}});

Retrieved from: here, here, and here

Note: While IE 8 and below don't support indexOf practically every other browser does.

Community
  • 1
  • 1
Downgoat
  • 13,771
  • 5
  • 46
  • 69