简体   繁体   中英

What is the most efficient way to search through a list of JavaScript objects and determine whether they contain the same values?

I have the following function which takes some values that the user has entered and creates JavaScript objects from those values, then puts those objects in an array and returns the array:

function createObjects() {
    var objectArray = []; 
    for (var i = 0; i < someCount; i++) {
        var object = {
            property1: someProperty1, 
            property2: someProperty2,
            property3: someProperty3,
            property4: someProperty4
        };
        objectArray.push(object);
    }
    return objectArray;
}

Now, I want to compare these objects' properties and determine whether any two contain all of the same values for property1 , property2 , property3 , and property4 . If any two of these objects have all four of the same values for these properties, I want a validation check to return false . Here is what I have so far:

function objectsAreUnique() {
    var objects = createObjects(); 
    for(var i = 0; i < objects.length; i++) {
        //need to determine whether all four of the properties are the same for any two objects
        //if(objectsAreSame) { return false; } 
    }
    return true; 
}

I have a few ideas, but I'm interested to see what is the most efficient way to achieve this. Thanks!

If you can guarantee that the properties will always be inserted in the same order (which will be the case if using an object literal as in your example), you can do this in ~O(n) using JSON.stringify and a Set :

function objectsAreUnique() {
    const objects = createObjects();
    return (new Set(objects.map(o => JSON.stringify(o)))).size == objects.length;
}
function objectsAreUnique() {
    var objects = createObjects(); 
    var stringifiedAndSorted = objects.map(obj => JSON.stringify(obj)).sort()
    for(var i = 0; i < stringifiedAndSorted.length-1; i++) {
        if(i === i+1) 
           return false;
    }
    return true; 
}

First, create a function to test whether two objects are the same. You can enter each property individually, or get creative with the JSON.stringify function

properties individually:

function objectsIdentical(obj1, obj2) {
    return obj1.property1 == obj2.property1 && obj1.property2 == obj2.property2 && obj1.property3 == obj2.property3 && obj1.property4 == obj2.property4;
}

JSON.stringify (recommended for objects with many properties)

function objectsIdentical(obj1, obj2) {
    return JSON.stringify(obj1).replace(/^.|.$/g, "").split(",").sort().join(",") == JSON.stringify(obj2).replace(/^.|.$/g, "").split(",").sort().join(",");
}    

Then, you can use a for loop to check if any of them are identical.

for (let i=0; i<objects.length-1; i++) {
    for (let j=i+1; j<objects.length; j++) {
        if (objectsIdentical(objects[i], objects[j])) {
            return false;
        }
    }
}
return true;

If you're familiar with the "some" function, you can use that.

return !objects.some((v, i) => objects.slice(i+1).some(w => objectsIdentical(v, w)))

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