Find if an object is subset of another object in javascript

*爱你&永不变心* 提交于 2020-12-04 15:57:44

问题


I need a function isSubset, which when given two objects compares its values and tell if one object is subset of another.

object1 = { pickUpLocation : {city : 'Hyderabad', state: 'Telangana' }};
object2 = { dist : 322, pickUpLocation:  {city : 'Hyderabad', state: 'Telangana' }};
isSubset(object1, object2); //should return true
object3 = { pickUpLocation : {city : 'Chennai', state: 'Telangana' }}
object4 = { dist : 322, pickUpLocation: {city : 'Hyderabad', state: 'Telangana' }}
isSubset(object3, object4) //should return false as city's value is different

回答1:


Using Lodash isMatch

_.isMatch({prop: 'object', id: 3}, {prop: 'object'})

Performs a partial deep comparison between object and source to determine if object contains equivalent property values.




回答2:


You can try to use isSubset package.

This is true

isSubset(
  { dist : 322, pickUpLocation:  {city : 'Hyderabad', state: 'Telangana' }},
  { pickUpLocation : {city : 'Hyderabad', state: 'Telangana' }}
);

This is false

isSubset(
  { dist : 322, pickUpLocation:  {city : 'Hyderabad', state: 'Telangana' }},
  { pickUpLocation : {city : 'Chennai', state: 'Telangana' }}
);



回答3:


It can be done pretty easily with lodash.

import _ from 'lodash'

const isSubset = (aSubset, aSuperset) => (
    _.every(aSubset, (val, key) => _.isEqual(val, aSuperset[key]))
)

Usage:

const object1 = { pickUpLocation: { city: 'Hyderabad', state: 'Telangana' }}
const object2 = { dist: 322, pickUpLocation:  { city: 'Hyderabad', state: 'Telangana' }}

isSubset(object1, object2)



回答4:


It's a bit late, but it might help someone looking for answer without using any external library.

isSubset = (superObj, subObj) => {
    return Object.keys(subObj).every(ele => {
        if (typeof subObj[ele] == 'object') {
            return isSubset(superObj[ele], subObj[ele]);
        }
        return subObj[ele] === superObj[ele]
    });
};

let object1 = { pickUpLocation : {city : 'Hyderabad', state: 'Telangana' }};
let object2 = { dist : 322, pickUpLocation:  {city : 'Hyderabad', state: 'Telangana' }};
console.log(isSubset(object2, object1));

let object3 = { pickUpLocation : {city : 'Chennai', state: 'Telangana' }}
let object4 = { dist : 322, pickUpLocation: {city : 'Hyderabad', state: 'Telangana' }}
console.log(isSubset(object4, object3));



回答5:


The above answer using lodash has limitation and doesn't cover all edge case scenarios. I just came up with this solution that matches all scenarios

import _ from 'lodash';

isSubset(obj1, obj2) {
  let matched = true;
  _.forEach(obj1, (value, key) => {
    if(!requirements || !_.isEqual(value, obj2[key])) {
      matched = false;
      return;
    }
  });
  return matched;
}

Case 1:

const obj1 = { foo: 'bar' };
const obj2 = { foo: 'bar', baz: 'qux' };
console.log(isSubset(obj1, obj2)); // true

Case 2:

const obj1 = { foo: 'bar' };
const obj2 = { foo: 'bar' };
console.log(isSubset(obj1, obj2)); // true

Case 3:

const obj1 = { foo: 'bar', baz: 'qux' };
const obj2 = { foo: 'bar'};
console.log(isSubset(obj1, obj2)); // false

Case 4:

const obj1 = undefiend;
const obj2 = undefiend;
console.log(isSubset(obj1, obj2)); // true

Case 5:

const obj1 = undefiend;
const obj2 = { foo: 'bar'};
console.log(isSubset(obj1, obj2)); // true

Case 6:

const obj1 = { foo: 'bar'};
const obj2 = undefiend;
console.log(isSubset(obj1, obj2)); // false



回答6:


Nima's first answer cannot be right since for a subset condition to be true, all (not just some) elements in the "smaller" set need to be contained in the "bigger" set. The rest is basically correct though, just replace some with every, and swap the two objects (big and small):

/**
 * Determine whether "small" is a subset of "big"
 * @see https://stackoverflow.com/questions/35737312/find-if-an-object-is-subset-of-another-object-in-javascript/48971177#48971177
 */
function isSubset(big, small) {
  const { every, isEqual } = _;
  return every(small, 
    (v, k) => isEqual(v, big[k])
  );
}

// test it!
var object1 = { pickUpLocation : {city : 'Hyderabad', state: 'Telangana' }};
var object2 = { dist : 322, pickUpLocation:  {city : 'Hyderabad', state: 'Telangana' }};
var a = {i:1, j:2, k:3}; var b = {i:1, j:2}; var c = {i:2, j:2};

console.log([
  isSubset(a, b),
  isSubset(a, c),
  isSubset(b, a),
  isSubset(object1, object2),
  isSubset(object2, object1)
]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>

PS: Here is another way of doing it, but it's probably slower since it copies stuff and does not stop early:

function isSubset(big, small) { 
  const { pick, isEqual } = _;
  return isEqual(pick(big, Object.keys(small)), small);
}



回答7:


Here is a simple solution:

  import _ from "lodash"
  // is a subset of b?
  function isSubset(a, b, merge = false) {
    const assign = merge ? _.merge : _.assign;
    var c = assign(_.cloneDeep(b), a);
    return _.isEqual(b, c);
  }



回答8:


function isSubset(obj1, obj2) {
  for (var key in obj2){
     if (JSON.stringify(obj2[key]) === JSON.stringify(obj1[key]))
        return true;
  }
  return false;
}

Edit: Now is generic, but if want it more generic you should see the follow link for the comparison https://stackoverflow.com/a/1144249/5965782




回答9:


In English:

Is there some key in object2 which satisifies the condition that there is deep equality between its value and object1?

Write that out:

_.some(                       // Is there some key
  object2,                    // in object2
  function(val, key) {             // which satisfies the condition that
    return _.isEqual(         // there is deep equality between
      val,                    // its value and
      object1[key]                 // object1?
    );
  }
);

In shorter form:

_.some(object2, function(val, key) { return _.isEqual(val, object1[key]); })

In ES6:

_.some(object2, (val, key) => _.isEqual(val, object1[key]))

My suggestion is to read through the lodash docs and learn all the APIs, or at least the main ones. For example, this problem will be very difficult to solve on your own if you are not aware of important routines such as _.some and _.isEqual. On the other hand, if you do know them, then it is quite trivial.



来源:https://stackoverflow.com/questions/35737312/find-if-an-object-is-subset-of-another-object-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!