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

Viewed 279

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"
    },
]
4 Answers

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

Related