我从服务器得到两个对象数组,如下所示:
- 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)