最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Check if any object in an array of objects contains all of the keyvalue pairs in another object - Stack Overflow

programmeradmin5浏览0评论

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

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
Share Improve this question edited Jun 15, 2016 at 20:35 Travis J 82.4k42 gold badges211 silver badges279 bronze badges asked Jun 15, 2016 at 20:33 Brian ZelipBrian Zelip 3,2217 gold badges38 silver badges50 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 3

You could use some array methods, like Array#map

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

and Array#every

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

and get the properties of source first with 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];       // pare 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)

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

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.

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

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

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论