简体   繁体   中英

Concise way to check an array of objects for a key/value pair?

What would be a short and concise way to find if each of the strings in the array below exists for some id in an object in the array? I know I could perform a for loop, but if I'm running multiple lookups it becomes tedious.

The below example should output false because one matches, one doesn't.

var array1= [
'j2n4k2j3n42k3j4n',
'ln23jk4n2njknn2n'
]


var array2 = [
    {
        fruit:"banana"
        origin:"florida"
        id:"j2n4k2j3n42k3j4n"
    },
    {
        fruit:"peach"
        origin:"georgia"
        id:"l2nkj2n3k4bj"
    },
]

Below code outputs a boolean. true if all ids are available in array2

 var array1 = [ 'j2n4k2j3n42k3j4n', "l2nkj2n3k4bj", 'ln23jk4n2njknn2n' ] var array2 = [{ fruit: "banana", origin: "florida", id: "j2n4k2j3n42k3j4n", }, { fruit: "peach", origin: "georgia", id: "l2nkj2n3k4bj" }, ] const results = array1.every(id => array2.find(item => item.id === id)) console.log(results)

If you want to find which element is found/not found, use the below method. It outputs an array with boolean values and has the same count as array1 . If an id is found the output array will have true in that array position.

 var array1 = [ 'j2n4k2j3n42k3j4n', "l2nkj2n3k4bj", 'ln23jk4n2njknn2n' ] var array2 = [{ fruit: "banana", origin: "florida", id: "j2n4k2j3n42k3j4n", }, { fruit: "peach", origin: "georgia", id: "l2nkj2n3k4bj" }, ] // Initial approach which works // const results = array1.map(id => Boolean(array2.find(item => item.id === id))); // Another approached as suggested by VLAZ and Phong in comments. `some` will check and return the boolean. const results = array1.map(id => array2.some(item => item.id === id)); console.log(results)

You can use Array.prototype.every() Array.prototype.some() and Destructuring.

 const array1 = ["j2n4k2j3n42k3j4n", "ln23jk4n2njknn2n"], array2 = [ { fruit: "banana", origin: "florida", id: "j2n4k2j3n42k3j4n", }, { fruit: "peach", origin: "georgia", id: "l2nkj2n3k4bj", }, ]; const result = array1.every((id1) => array2.some(({ id }) => id === id1)); console.log(result);

You could use Array.prototype.idexOf or more elegant Array.prototype.includes

 let array1 = [ 'j2n4k2j3n42k3j4n', "l2nkj2n3k4bjx", 'ln23jk4n2njknn2n' ] let array2 = [{ fruit: "banana", origin: "florida", id: "j2n4k2j3n42k3j4n", }, { fruit: "peach", origin: "georgia", id: "l2nkj2n3k4bj" }, ] console.log("1st Approach"); array2.forEach(e => { if(array1.indexOf(e.id) < 0 ) console.log(false); else console.log(true); }); console.log("2nd Approach"); array2.forEach(e => { if(array1.includes(e.id)) console.log(true); else console.log(false); });

Solution 1: Readable code, but not good in terms of performance.

You can use Array#every combined with Array#some

 var array1 = ['j2n4k2j3n42k3j4n', 'ln23jk4n2njknn2n']; var array2 = [{fruit: "banana", origin: "florida", id: "j2n4k2j3n42k3j4n"}, {fruit: "peach", origin: "georgia", id: "l2nkj2n3k4bj" }]; const checkIncludes = (a1, a2) => a1.every(s => a2.some(({id}) => s === id)); console.log(checkIncludes(array1, array2)); // false --> Because one matches, one doesnt. console.log(checkIncludes(["j2n4k2j3n42k3j4n"], array2)); // true --> Because one matches

Solution 2: Better performance

You can convert the array2 into object named normalizedData , then finding cost just takes O(1)

 var array1 = ['j2n4k2j3n42k3j4n', 'ln23jk4n2njknn2n']; var array2 = [{fruit: "banana", origin: "florida", id: "j2n4k2j3n42k3j4n"}, {fruit: "peach", origin: "georgia", id: "l2nkj2n3k4bj" }]; const checkIncludes = (aString, aObject) => { const normalizedData = aObject.reduce((acc, {id}) => { acc[id] = id; return acc; },{}); return aString.every(s => normalizedData[s]); } console.log(checkIncludes(array1, array2)); // false --> Because one matches, one doesnt. console.log(checkIncludes(["j2n4k2j3n42k3j4n"], array2)); // true --> Because one matches

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