如何知道对象是否包含另一个对象

时间:2015-05-14 20:10:26

标签: javascript

我试图找到一个能够说明对象B是否包含对象A的所有属性和值的库(而不是相反的!)。

这意味着我发现的图书馆有两件事无法处理:

  1. 对象B可以拥有比对象A更多的键,它可以是 真。
  2. 对象B的数组中的项可能比对象多 A,它可能是真的。
  3. 这基本上是lodash的方法_.difference()所做的,但仅适用于数组中的项目。

    我找到了像deep-diff这样有趣的图书馆,但是我需要的东西。

    我可以编写一些可以完成工作的代码,但我确信其他人在此之前就已满足了这一需求。

    以下是2个对象的示例:

    var A = {
      name: 'toto',
      pets: [ { name: 'woof', kind: 'dog' } ]
    };
    
    var B = {
      name: 'toto',
      pets: [ { name: 'gulp', kind: 'fish' }, { name: 'woof', kind: 'dog' } ],
      favoriteColor: 'blue'
    };
    

    这里,A包括B,因为我们可以在B中找到A的每个属性和值。 但像差异这样的图书馆会说不,因为这不是第一项,而是第二项"宠物"它等于A,B有一个额外的属性" favoriteColor"。

    你知道一个能够进行这种比较的图书馆吗?

1 个答案:

答案 0 :(得分:1)

您可以使用评论中链接的deepCompare的修改版本。真的,你只需要通过密钥长度比较,似乎。



// where b has all of a
function deepHas(a, b) {
  if (typeof a !== typeof b) {
    return false;
  }
  if (typeof a !== 'object') {
    return a === b;
  }

  // you may need to polyfill array higher-order functions here
  if(Array.isArray(a) && Array.isArray(b)) {
    return a.every(function(av) {
      return b.indexOf(av) !== -1;
    });
  }
  
  if (Object.keys(a).length > Object.keys(b).length) {
    return false;
  }
  for (var k in a) {
    if (!(k in b)) {
      return false;
    }
    if (!deepHas(a[k], b[k])) {
      return false;
    }
  }
  return true;
}


var a1 = {
  foo: ['a', 'b', 'c'],
  bar: 'bar',
  baz: {
    baz: {
      baz: 'wee'
    }
  }
};

var b1 = {
  foo: ['a', 'b', 'c', 'd'],
  bar: 'bar',
  baz: {
    baz: {
      baz: 'wee',
      whatever: 'wat'
    }
  },
  ok: 'test'
};

console.log('b1 has all of a1', deepHas(a1, b1));

var a2 = {
  foo: ['a', 'b', 'c'],
  bar: 'bar',
  baz: {
    baz: {
      baz: 'wee'
    }
  }
};

var b2 = {
  foo: ['a', 'b', 'c'],
  baz: {
    baz: {
      baz: 'wee'
    }
  }
};

console.log('b2 does not have all of a2', !deepHas(a2, b2));

console.log('["a","b"] has ["b"]', deepHas(["b"], ["a","b"]));

console.log('{foo: ["a","b"]} has {foo: ["b"]}', deepHas({ foo: ["b"] }, { foo:["a","b"] }));