Найдите, является ли объект подмножеством другого объекта в 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
8 ответов
На Английском Языке:
здесь некоторые ключ в
object2
что satisifies условии, что есть глубокий равнойity между его значением и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]))
мое предложение-прочитать лодаш docs и узнать все API, или, по крайней мере основные из них. Например, это проблема будет очень трудно решить самостоятельно, если вы не знаете о важных подпрограмм, таких как _.some
и _.isEqual
. С другой стороны, если вы их знаете, то это довольно тривиально.
вы можете попробовать использовать 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'
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)
Использование Lodash isMatch
_.isMatch({prop: 'object', id: 3}, {prop: 'object'})
выполняет частичное глубокое сравнение между объектом и источником, чтобы определить, содержит ли объект эквивалентные значения свойств.
приведенный выше ответ с использованием 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
первый ответ Nima не может быть правильным, так как для условия подмножества должно быть true, все (не просто некоторые) элементы в" меньшем "наборе должны содержаться в" большем " наборе. Остальное в основном правильно, хотя, просто замените 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: вот еще один способ сделать это, но, вероятно, медленнее, так как он копирует stuff и не останавливается рано:
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);
}
function isSubset(obj1, obj2) {
for (var key in obj2){
if (JSON.stringify(obj2[key]) === JSON.stringify(obj1[key]))
return true;
}
return false;
}
Edit: Now является общим, но если вы хотите, чтобы он был более общим, вы должны увидеть ссылку для сравнения https://stackoverflow.com/a/1144249/5965782