如何使用javascript或lodash从对象数组中删除不匹配的对象

我从服务器获取两个对象数组,如下所示:

var duplicateTestData = [ { licenseId: 'xxx', batchId: '123', reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time) }, { licenseId: 'yyy', batchId: '124', reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time) }, { 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', batchId: '123', licenseId: 'xxx', createType: 'DataUpload' }, { reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time), testType: 'P1', productType: 'Flower', batchId: '124', licenseId: 'yyy', createType: 'DataUpload' }, { reportDate: Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time), testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'aaa', createType: 'DataUpload' }, { reportDate: Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time), testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'zzz', createType: 'DataUpload' } ] 

我正试图从finalResult对象只获取不匹配的对象,最终的结果是这样的:

 [ { reportDate: Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time), testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'zzz', 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)', testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'zzz', createType: 'DataUpload' } ] 

好吧, 它工作 ,但这大多是垃圾。 它并不完全准确地描述你想要做的比较。 它的方式太具体了,一旦有关于你的数据发生了变化,它就会中断。

继续阅读,我们可以学习一些乐趣。


所有对象相等(键和值)…

我将首先制定几个通用程序,以便更好地描述解决scheme。

你会注意到这个解决scheme与其他解决scheme相比,它不会假设你的数据的内部。 这个解决scheme可以不关心你的对象中使用的实际键名称。

这意味着我们不会触及任何batchIdlicenseIdreportDate 。 在这种情况下,通用程序可以解决所有问题,最好的部分就是你可以一遍又一遍地处理你想要处理的任何数据。

 // 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:10}, {a:2,b:20}, {a:3,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}] 
 var res = _.filter(finalResult, function(item) { return !_.find(duplicateTestData, { batchId: item.batchId, licenseId: item.licenseId, reportDate: item.reportDate }); }); console.log(res); 

的jsfiddle

您可以使用散列表并返回一个新的结果集,而不会在迭代它时拼接数组。

 function getKey(o) { return o.licenseId + '|' + o.reportDate + '|' + o.batchId; } var duplicateTestData = [{ licenseId: 'xxx', batchId: '123', reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' }, { licenseId: 'yyy', batchId: '124', reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' }, { licenseId: 'aaa', batchId: '145', reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' }], finalResult = [{ reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)', license: {}, testType: 'P1', productType: 'Flower', batchId: '123', licenseId: 'xxx', createType: 'DataUpload' }, { reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)', testType: 'P1', productType: 'Flower', batchId: '124', licenseId: 'yyy', createType: 'DataUpload' }, { reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)', testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'aaa', createType: 'DataUpload' }, { reportDate: 'Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time)', testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'zzz', createType: 'DataUpload' }], hash = Object.create(null), result = []; duplicateTestData.forEach(function (a) { hash[getKey(a)] = true; }); result = finalResult.filter(function (a) { return !hash[getKey(a)]; }); console.log(result); 
 for (var a = 0; a < duplicateTestData.length; a++) { var dt = duplicateTestData[a]; var dtr = new Date(dt.reportDate + ''); for (var b = 0; b < finalResult.length; b++) { var fr = finalResult[b]; var frr = new Date(fr.reportDate + ''); //define your logic how to match two objects if (dtr.getTime() !== frr.getTime() && dt.batchId !== fr.batchId) { //object matched. remove it from array var removed = finalResult.splice(b, 1); console.log('items removed', removed); } } } //print finalResult array for (var c = 0; c < finalResult.length; c++) { console.log(finalResult[c]); } 

使用lodash:

 duplicateTestData.reduce( _.reject, finalResult ); 
 var duplicateTestData = [ { licenseId: 'xxx', batchId: '123', reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' }, { licenseId: 'yyy', batchId: '124', reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)' }, { 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', batchId: '123', licenseId: 'xxx', createType: 'DataUpload' }, { reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)', testType: 'P1', productType: 'Flower', batchId: '124', licenseId: 'yyy', createType: 'DataUpload' }, { reportDate: 'Fri Dec 11 2015 00:00:00 GMT+0530 (India Standard Time)', testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'aaa', createType: 'DataUpload' }, { reportDate: 'Fri Dec 14 2015 00:00:00 GMT+0530 (India Standard Time)', testType: 'P1', productType: 'Flower', batchId: '145', licenseId: 'zzz', createType: 'DataUpload' } ] console.log( duplicateTestData.reduce( _.reject, finalResult ) ); 
 <script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.min.js"></script>