检查对象数组中的任何对象是否包含另一个对象中的所有 key/value 对

Check if any object in an array of objects contains all of the key/value pairs in another object

我正在尝试编写一个函数来查看对象数组(第一个参数)和 returns 包含给定的所有 key/value 对的所有对象的数组对象(第二个参数)。

我下面的代码仅在 source 对象(第二个参数)包含一对 key/value 时才有效。当 source 对象有两个或更多 key/value 对时,结果不符合预期。

如何在 source 对象中考虑多个 key/value 对?

function findObjects(collection, source) {
  var result = [];

  for (i=0; i<collection.length; i++) {
    for (var prop in source) {
      if (collection[i].hasOwnProperty(prop) && collection[i][prop] == source[prop]) {
        console.log('Collection\'s object ' + [i] + ' contains the source\'s key:value pair ' + prop + ': ' + source[prop] + '!');
        result.push(collection[i]);
      } else {
        console.log('fail');
      }
    }
  }

  console.log('The resulting array is: ' + result);
  return result;
}

findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 });

// only the first object should be returned since it contains both "a":1 and "b":2
function findObjects(collection, source) {
    var result = [];

    for (i=0; i<collection.length; i++) {
        var matches = true;
        for (var prop in source) {
            if (!collection[i].hasOwnProperty(prop) || collection[i][prop] !== source[prop]) {
                matches = false;
                break;
            }
        }
        if (matches) {
            result.push(collection[i]);
        }
    }
    return result;
}

基本上,您必须检查所有属性并确保它们匹配,然后才 然后 将其添加到您的 result 数组。

你可以使用一些数组方法,比如Array#map

The map() method creates a new array with the results of calling a provided function on every element in this array.

Array#every

The every() method tests whether all elements in the array pass the test implemented by the provided function.

并首先使用Object.keys获取源的属性。

The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).

function findObjects(collection, source) {
    var keys = Object.keys(source);          // get all properties of source
    return collection.filter(function (c) {  // filter collection
        return keys.every(function (k) {     // check every key
            return c[k] === source[k];       // compare value of collection and source
        });
    });
}

console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));

在 ES6 语法中相同(阅读更多:Arrow functions

Basically this style is a short writing of

function (x) { return y; }

became

          x =>        y

function findObjects(collection, source) {
    const keys = Object.keys(source);
    return collection.filter(c => keys.every(k => c[k] === source[k]));
}

console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));

使用Object.keysArray.forEachArray.some函数的解决方案:

function findObjects(arr, source) {
    var keys = Object.keys(source), result = [];
    arr.forEach(function(v){
        !keys.some((k) => source[k] !== v[k]) && result.push(v);
    });

    return result;
}

console.log(findObjects([{ "a": 1, "b": 2 }, { "a": 1 }, { "b": 2, "c": 2 }], { "a": 1, "b": 2 }));
// it will output [{"a":1,"b":2}]