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

时间:2022-09-25 09:19:12

I'm trying to write a function that looks through an array of objects (the first argument) and returns an array of all objects that contain all of the key/value pairs of a given object (the second argument).

我正在尝试编写一个查看对象数组(第一个参数)的函数,并返回包含给定对象(第二个参数)的所有键/值对的所有对象的数组。

My code below works only if the source object (the second argument) contains one key/value pair. When the source object has two or more key/value pairs, the result isn't as expected.

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

How to account for more than one key/value pair in the source object?

如何在源对象中考虑多个键/值对?

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

3 个解决方案

#1


1  

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

Basically, you have to check ALL properties and make sure they match, and then only then do you add it to your result array.

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

#2


2  

You could use some array methods, like Array#map

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

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

map()方法创建一个新数组,其结果是在此数组中的每个元素上调用提供的函数。

and Array#every

和数组#every

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

every()方法测试数组中的所有元素是否都通过了由提供的函数实现的测试。

and get the properties of source first with Object.keys.

首先使用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).

Object.keys()方法返回给定对象自己的可枚举属性的数组,其顺序与for ... in循环提供的顺序相同(不同之处在于for-in循环枚举原型链中的属性为好)。

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

The same in ES6 syntax (read more: Arrow functions)

ES6语法相同(阅读更多:箭头功能)

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

#3


1  

The solution using Object.keys, Array.forEach and Array.some functions:

使用Object.keys,Array.forEach和Array.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}]

#1


1  

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

Basically, you have to check ALL properties and make sure they match, and then only then do you add it to your result array.

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

#2


2  

You could use some array methods, like Array#map

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

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

map()方法创建一个新数组,其结果是在此数组中的每个元素上调用提供的函数。

and Array#every

和数组#every

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

every()方法测试数组中的所有元素是否都通过了由提供的函数实现的测试。

and get the properties of source first with Object.keys.

首先使用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).

Object.keys()方法返回给定对象自己的可枚举属性的数组,其顺序与for ... in循环提供的顺序相同(不同之处在于for-in循环枚举原型链中的属性为好)。

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

The same in ES6 syntax (read more: Arrow functions)

ES6语法相同(阅读更多:箭头功能)

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

#3


1  

The solution using Object.keys, Array.forEach and Array.some functions:

使用Object.keys,Array.forEach和Array.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}]