我从服务器得到两个对象数组,如下所示:
var duplicateTestData = [ { licenseId: 'xxx',batchId: '123',reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time) },{ licenseId: 'yyy',batchId: '124',{ licenseId: 'aaa',batchId: '145',reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time) } ]; var finalResult = [ { reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time),license: {},testType: 'P1',productType: 'Flower',licenseId: 'xxx',createType: 'DataUpload' },{ reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time),licenseId: 'yyy',licenseId: 'aaa',{ reportDate: Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time),licenseId: 'zzz',createType: 'DataUpload' } ]
我试图从finalResult对象中只获取不匹配的对象,最终的结果将是这样的:
[ { reportDate: Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time),createType: 'DataUpload' } ]
我正在尝试这个,但没有得到正确的结果:
for(var j=0;j < duplicateTestData.length;j++){ for (var i = 0; i < finalResult.length; i++) { if ( (finalResult[i].licenseId == duplicateTestData[j].licenseId) && (finalResult[i].reportDate == duplicateTestData[j].reportDate) && (finalResult[i].batchId == duplicateTestData[j].batchId) ) { finalResult.splice(i,1); break; } } } console.log(finalResult);
解决方法
简单的出路
finalResult.filter(({batchId:a,licenseId:b,reportDate:c}) => duplicateTestData.find(({batchId:x,licenseId:y,reportDate:z}) => a === x && b === y && c === z) === undefined) => [ { reportDate: 'Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time)',createType: 'DataUpload' } ]
好的,它的作品,但这大多是垃圾.它并没有完全准确地描述你所做的比较.它的方式太具体了,一旦你的数据发生变化,它就会破裂.
继续阅读,我们可以学习一些乐趣.
所有(键和值)的对象相等…
我将从制定几个通用程序开始,以便更好地描述我们的问题的解决方案.
与其他方案相比,您将注意到的这个解决方案是,它不会对数据的内部构成假设.该解决方案不太在意对象中使用的实际键名称.
这意味着我们不会触摸任何batchId,licenseId或reportDate.通用过程可以解决这种情况下的所有事情,最好的部分是您可以一次又一次地使用您希望处理的任何数据.
// arrayCompare :: (a -> b -> Bool) -> [a] -> [b] -> Bool const arrayCompare = f=> ([x,...xs])=> ([y,...ys])=> { if (x === undefined && y === undefined) return true else if (! f (x) (y)) return false else return arrayCompare (f) (xs) (ys) } // keys :: Object(k:v) -> [k] const keys = Object.keys // objectCompare :: (v -> v -> Bool) -> Object(k:v) -> Object(k:v) -> Bool const objectCompare = f=> a=> b=> arrayCompare (x=> y=> f (a[x]) (b[y]) && f (a[y]) (b[y])) (keys(a)) (keys(b)) // objectEqual :: Object -> Object -> Bool const objectEqual = objectCompare (x=> y=> x === y) // sample data let xs = [ {a:1,b:10},{a:2,b:20},{a:3,b:30} ] let ys = [ {a:1,b:30},{a:4,b:40} ] // return all ys that are not present in xs var result = ys.filter(y=> xs.find(objectEqual(y)) === undefined) console.log(result) // [{a:4,b:40}]
好厉害
您将不得不调整此解决方案有些因为您没有比较所有对象键.在finalResult中的对象具有比duplicateTestData中的对象更多的键,因此有1:1个匹配.
简单来说,如果将x = {a:1}与y = {a:1,b:2}进行比较,则将x = {a:1}视为“匹配”,只要x中的所有键值都匹配所有键: y中的值
如果我们使用上面的objectEquals比较器,没有任何东西将被过滤掉finalResult,因为没有任何对象将匹配在duplicateTestData中找到的对象.既然这不是你想要的,那么我们来定义一个可以为你的案例工作的比较器
// subsetObjectEquals :: Object -> Object -> Bool const subsetObjectEquals = objectCompare (x=> y=> y === undefined || x === y) // this time use subsetObjectEquals var result = finalResult.filter(x=> duplicateTestData.find(subsetObjectEquals(x)) === undefined)
subsetObjectEquals的工作方式有所不同.我真的不会想到一个更好的名字,因为这是一个有点奇怪的比较.当y未定义时,表示该值的关键字不存在于“子集对象”中,因此不需要进行比较
subsetObjectEquals(a,b) // returns true if all key:value pairs in `a` match all key:value pairs in `b` // otherwise returns false
充分的工作实例
我附上了一个实际使用您问题中包含的输入数据的完整代码段.在这里展开,运行它来看它的工作
// arrayCompare :: (a -> b -> Bool) -> [a] -> [b] -> Bool const arrayCompare = f=> ([x,...ys])=> { if (x === undefined && y === undefined) return true else if (! f (x) (y)) return false else return arrayCompare (f) (xs) (ys) } // keys :: Object(k:v) -> [k] const keys = Object.keys // objectCompare :: (v -> v -> Bool) -> Object(k:v) -> Object(k:v) -> Bool const objectCompare = f=> a=> b=> arrayCompare (x=> y=> f (a[x]) (b[x]) && f (a[y]) (b[y])) (keys(a)) (keys(b)) // objectEqual :: Object -> Object -> Bool const objectEqual = objectCompare (x=> y=> x === y) // subsetObjectEquals :: Object -> Object -> Bool const subsetObjectEquals = objectCompare (x=> y=> y === undefined || x === y) // your data var duplicateTestData = [{ licenseId: 'xxx',reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' },{ licenseId: 'yyy',{ licenseId: 'aaa',reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' } ]; var finalResult = [ { reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)',createType: 'DataUpload' },{ reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)',{ reportDate: 'Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time)',createType: 'DataUpload' } ] // get all finalResult items that do not subsetObjectEqual items in duplicateTestData var result = finalResult.filter(x=> duplicateTestData.find(subsetObjectEquals(x)) === undefined) console.log(result)