简体   繁体   中英

Find object in array and then edit it

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]

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>'; 

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM