我正在为Lodash的_.isEqualWith
使用自定义比较功能。我想要一个可以正常工作的函数:
const comparisonFunc = /* ...TBC... */
// Should be true:
_.isEqualWith({ a: undefined }, { }, comparisonFunc);
// Should still be false, as normal:
_.isEqualWith({ a: undefined }, { a: 123 }, comparisonFunc);
// Should still be false, as normal:
_.isEqualWith([undefined], [ ], comparisonFunc);
即对于比较中的任何对象(递归),应将设置为undefined
的属性视为不存在。
答案 0 :(得分:0)
这不是我想要的那么简单,但是我找到了解决方案:
const comparisonFunc = (a, b) => {
if (_.isArray(a) || _.isArray(b)) return;
if (!_.isObject(a) || !_.isObject(b)) return;
if (!_.includes(a, undefined) && !_.includes(b, undefined)) return;
// Call recursively, after filtering all undefined properties
return _.isEqualWith(
_.omitBy(a, (value) => value === undefined),
_.omitBy(b, (value) => value === undefined),
comparisonFunc
);
}
// Should be true:
_.isEqualWith({ a: undefined }, { }, comparisonFunc); // = true
// Should still be false, as normal:
_.isEqualWith({ a: undefined }, { a: 123 }, comparisonFunc); // = false
// Should still be false, as normal:
_.isEqualWith([undefined], [ ], comparisonFunc); // = false
很高兴接受其他答案:-)
答案 1 :(得分:0)
您只需检查Wheather是一个数组还是对象,并相应地过滤undefined
个成员,然后递归调用即可。
const comp = (a, b) => {
var A, B,
fn = v => !_.isUndefined(v),
filter = _.isArray(a) ? _.filter : _.pickBy;
if (_.isObject(a)) {
A = filter(a, fn)
B = filter(b, fn)
} else { return _.isEqual(a, b); }
if (_.keys(a).length === _.keys(A).length && _.keys(b).length === _.keys(B).length) {return}
return _.isEqualWith(A, B, comp);
};
var a1 = [10, 10, undefined, undefined, 10],
a2 = [undefined, undefined, 10, undefined, 10, undefined, 10],
o1 = {x: 10, y:undefined, z: 20, v: a1}
o2 = {x: 10, z: 20, v: a2};
console.log('a1 with a2: ', _.isEqualWith(a1, a2, comp));
console.log('o1 with o2: ', _.isEqualWith(o1, o2, comp));
console.log('a1 with o2: ', _.isEqualWith(a1, o2, comp));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
检查密钥长度和return语句是否可以确定我们必须在内部遍历(在上次迭代中删除了未定义的值)还是需要再次遍历(在此迭代中删除了未定义的值)>
答案 2 :(得分:0)
与 Tim Perry 的回答相同,仅使用 TypeScript 和 lodash/fp
function matchMissingWithUndefined(a: {}, b: {}) {
const hasUndefined = _.includes(undefined);
if (_.isPlainObject(a) && _.isPlainObject(b) && (hasUndefined(a) || hasUndefined(b))) {
const onlyDefined = _.omitBy((value) => value === undefined);
return _.isEqualWith(matchMissingWithUndefined, onlyDefined(a), onlyDefined(b));
}
}
_.isEqualWith(matchMissingWithUndefined, { a: undefined }, { }); // true
答案 3 :(得分:0)
在省略 null
值后,我们应该以某种方式绕过对 customizer
的初始调用,而无需再次检查对象是否没有 includes
null
值。
我为此目的发明了某种不错的自行车:
const compareWithoutNullProperties = (a: any, b: any) =>
isPlainObject(a) && isPlainObject(b)
? isEqualWith(
omitBy(a, (value) => value == null),
omitBy(b, (value) => value == null),
(a: any, b: any, key?: number | string | symbol): boolean | undefined =>
// Next initial call should be ignored.
key != null ? compareWithoutNullProperties(a, b) : undefined,
)
: undefined;
const isEqualWithoutNullProperties = (a: any, b: any) =>
isEqualWith(a, b, compareWithoutNullProperties);
返回 true
的测试:
isEqualWithoutNullProperties({ a: undefined }, {});
isEqualWithoutNullProperties({ a: null }, {});
isEqualWithoutNullProperties([{ a: undefined }], [{}]);
isEqualWithoutNullProperties([{ a: null }], [{}]);
isEqualWithoutNullProperties({ a: { a: undefined } }, { a: {} });
isEqualWithoutNullProperties({ a: { a: null } }, { a: {} });
isEqualWithoutNullProperties({ a: [{ a: undefined }] }, { a: [{}] });
isEqualWithoutNullProperties({ a: [{ a: null }] }, { a: [{}] });
返回 false
的测试:
isEqualWithoutNullProperties([undefined], []);
isEqualWithoutNullProperties([null], []);
isEqualWithoutNullProperties([undefined], [1]);
isEqualWithoutNullProperties([null], [1]);
isEqualWithoutNullProperties({ a: undefined }, { a: 1 });
isEqualWithoutNullProperties({ a: null }, { a: 1 });
isEqualWithoutNullProperties([{ a: undefined }], [{ a: 1 }]);
isEqualWithoutNullProperties([{ a: null }], [{ a: 1 }]);
isEqualWithoutNullProperties({ a: { a: undefined } }, { a: { a: 1 } });
isEqualWithoutNullProperties({ a: { a: null } }, { a: { a: 1 } });
isEqualWithoutNullProperties({ a: [{ a: undefined }] }, { a: [{ a: 1 }] });
isEqualWithoutNullProperties({ a: [{ a: null }] }, { a: [{ a: 1 }] });