问题
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
object2which satisifies the condition that there is deep equality between its value andobject1?
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