查找一个对象是否是 javascript 中另一个对象的子集
Find if an object is subset of another object in javascript
我需要一个函数isSubset,当给定两个对象时,它会比较其值并判断一个对象是否是另一个对象的子集。
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
使用 Lodash isMatch
_.isMatch({prop: 'object', id: 3}, {prop: 'object'})
在对象和源之间执行部分深度比较,以确定对象是否包含等效的属性值。
有点晚了,但它可能会帮助人们在不使用任何外部库的情况下寻找答案。
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));
它可以很容易地用lodash完成。
import _ from 'lodash'
const isSubset = (aSubset, aSuperset) => (
_.every(aSubset, (val, key) => _.isEqual(val, aSuperset[key]))
)
用法:
const object1 = { pickUpLocation: { city: 'Hyderabad', state: 'Telangana' }}
const object2 = { dist: 322, pickUpLocation: { city: 'Hyderabad', state: 'Telangana' }}
isSubset(object1, object2)
您可以尝试使用 isSubset 包。
这是真的
isSubset(
{ dist : 322, pickUpLocation: {city : 'Hyderabad', state: 'Telangana' }},
{ pickUpLocation : {city : 'Hyderabad', state: 'Telangana' }}
);
这是错误的
isSubset(
{ dist : 322, pickUpLocation: {city : 'Hyderabad', state: 'Telangana' }},
{ pickUpLocation : {city : 'Chennai', state: 'Telangana' }}
);
上述使用 lodash 的答案有局限性,并未涵盖所有边缘情况。我刚刚想出了这个适用于所有场景的解决方案
import _ from 'lodash';
isSubset(obj1, obj2) {
let matched = true;
_.forEach(obj1, (value, key) => {
if(!requirements || !_.isEqual(value, obj2[key])) {
matched = false;
return;
}
});
return matched;
}
案例1:
const obj1 = { foo: 'bar' };
const obj2 = { foo: 'bar', baz: 'qux' };
console.log(isSubset(obj1, obj2)); // true
案例2:
const obj1 = { foo: 'bar' };
const obj2 = { foo: 'bar' };
console.log(isSubset(obj1, obj2)); // true
案例3:
const obj1 = { foo: 'bar', baz: 'qux' };
const obj2 = { foo: 'bar'};
console.log(isSubset(obj1, obj2)); // false
案例4:
const obj1 = undefiend;
const obj2 = undefiend;
console.log(isSubset(obj1, obj2)); // true
案例5:
const obj1 = undefiend;
const obj2 = { foo: 'bar'};
console.log(isSubset(obj1, obj2)); // true
案例6:
const obj1 = { foo: 'bar'};
const obj2 = undefiend;
console.log(isSubset(obj1, obj2)); // false
function isSubset(obj1, obj2) {
for (var key in obj2){
if (JSON.stringify(obj2[key]) === JSON.stringify(obj1[key]))
return true;
}
return false;
}
编辑:现在是通用的,但如果想要它更通用,您应该看到以下链接进行比较https://stackoverflow.com/a/1144249/5965782
Nima 的第一个答案不可能是正确的,因为要使子集条件为真,"较小"集合中的所有 (不仅仅是某些)元素都需要包含在"较大"集合中。其余的基本上是正确的,只需将some
替换为every
,并交换两个对象(big
和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:这是另一种方法,但它可能会更慢,因为它会复制东西并且不会提前停止:
function isSubset(big, small) {
const { pick, isEqual } = _;
return isEqual(pick(big, Object.keys(small)), small);
}
这是一个简单的解决方案:
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);
}
也有点晚了,但这是另一个不需要任何外部库的解决方案。 我基于@Akshay Kapoor 的答案,但这个答案处理日期和其他定义 valueOf() 的对象相等:
const isSubset = (superObj, subObj) =>
superObj === subObj ||
typeof superObj === "object" &&
typeof subObj === "object" && (
subObj.valueOf() === superObj.valueOf() /* dates & ? */ ||
Object.keys(subObj).every(k => isSubset(superObj[k], subObj[k]))
);
function isSubset(obj1, obj2) {
const matches = [];
for(const n1 in obj1) {
let match = false;
for(const n2 in obj2) {
if(n1 == n2 && obj1[n1] == obj2[n2]) {
match = true;
break;
}
}
matches.push(match);
}
return matches.every(Boolean);
}
英文:
object2
中是否有一些关键满足其值与object1
之间存在深度相等的条件?
写出来:
_.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?
);
}
);
以较短的形式:
_.some(object2, function(val, key) { return _.isEqual(val, object1[key]); })
在 ES6 中:
_.some(object2, (val, key) => _.isEqual(val, object1[key]))
我的建议是通读 lodash 文档并学习所有 API,或者至少是主要的 API。例如,如果您不了解重要的例程,例如 _.some
和 _.isEqual
.另一方面,如果你确实了解他们,那么这是相当微不足道的。
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- Javascript(Angular)从一个对象数组到第二个数组查找值
- 对一个对象使用reduce可以返回一个没有't在数组中包含目标字母
- AngularJS&JSON-从Previous&下一个对象
- jQuery$.inArray()总是返回-1和一个对象数组
- javascript处理一个对象数组以获得一个新的对象数组
- javascript函数,它接受两个输入:一个对象和一个键,并返回对象中该键的相应值
- 你能用来自数组的属性名称生成一个对象吗
- 预期响应包含一个对象,但在angular js中得到一个数组错误
- Protractor:element.getText()返回一个对象,而不是String
- 如何使用jQuery添加另一个对象的高度作为边距
- 计算从一个对象到另一个对象的路径并沿其移动
- 如何将一个对象添加到每个对象数组中
- 为了避免创建全局变量,可以将所有变量分配给一个对象吗
- 将javascript对象(属性+值)合并到一个对象中
- 尝试简化检查对象键是否为true并将其推送到另一个对象
- 从 javascript 中的对象方法返回一个对象
- 是否可以创建一个对象,该对象是另一个对象的子集,而不会丢失javascript中的引用
- 查找一个对象是否是 javascript 中另一个对象的子集
- 是否有更好/更短的模式来将一个对象的属性子集设置到另一个对象上?