Javascript 如何对待失踪和失踪;Lodash和#x27中同等的未定义属性;这是我的荣幸

Javascript 如何对待失踪和失踪;Lodash和#x27中同等的未定义属性;这是我的荣幸,javascript,lodash,equality,Javascript,Lodash,Equality,我正在与Lodash的自定义比较函数进行斗争。我想要一个这样的函数: const comparisonFunc = /* ...TBC... */ // Should be true: _.isEqualWith({ a: undefined }, { }, comparisonFunc); // Should still be false, as normal: _.isEqualWith({ a: undefined }, { a: 123 }, comparisonFunc); //

我正在与Lodash的自定义比较函数进行斗争。我想要一个这样的函数:

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);

也就是说,对于比较中的任何对象(递归),设置为
未定义的属性应被视为不存在的属性。

这并不像我希望的那么简单,但我找到了一个解决方案:

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

如果有人有更简单或更好的答案,你很乐意接受其他答案:-)

你只需检查它们是数组还是对象,并相应地过滤
未定义的
成员,然后递归调用即可

const comp=(a,b)=>{
变量A,B,
fn=v=>!\u.未定义(v),
过滤器=u.isArray(a)?u.filter:u.pickBy;
如果(uu.isObject(a)){
A=过滤器(A,fn)
B=过滤器(B,fn)
}else{return u.isEqual(a,b);}
如果({u0.keys(a).length=={u0.keys(a).length&&{u0.keys(b).length=={u0.keys(b).length}
返回与(A、B、comp)相等;
};
变量a1=[10,10,未定义,未定义,10],
a2=[未定义,未定义,10,未定义,10,未定义,10],
o1={x:10,y:undefined,z:20,v:a1}
o2={x:10,z:20,v:a2};
console.log('a1与a2:',0.isEqualWith(a1,a2,comp));
console.log('o1与o2:',0.isEqualWith(o1,o2,comp));
console.log('a1与o2:',0.isEqualWith(a1,o2,comp))

与蒂姆·佩里的答案相同,只有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


似乎不可能。似乎如果前两个参数的键不匹配,那么该方法不会对所有值进行递归比较。您可以为两个对象创建所有匹配的键,也可以编写其他函数来进行比较。因此,它是一个平面数据,或者数据可以达到任何深度。这些例子只是简单的数据(对象或数组),但问题在于深度和深度吗?@KoushikChatterjee是的,任何深度。它以递归方式工作,就像
isEqualWith
正常工作一样。请尝试避免
忽略
而改用
pickBy
,这样做是正确的,但代码太多,而且不容易阅读。。