如何使用 javascript 或 lodash 从对象数组中删除不匹配的对象
How to remove unmatched objects from array of objects using javascript or 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);
var res = _.filter(finalResult, function(item) {
return !_.find(duplicateTestData, {
batchId: item.batchId,
licenseId: item.licenseId,
reportDate: item.reportDate
});
});
console.log(res);
你可以使用哈希 table 和 return 一个新的结果集,而不会在迭代时出现拼接数组的问题。
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);
ES6
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' }],
map = duplicateTestData.reduce((r, a) => r.set(getKey(a)), new Map),
result = finalResult.filter(a => !map.has(getKey(a)));
console.log(result);
简单的出路
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' } ]
好的,有效,但这主要是垃圾。它没有完全准确地描述您要进行的比较。它太具体了,一旦你的数据发生变化,它就会崩溃。
继续阅读,我们可以学到一些有趣的东西。
所有(键和值)的对象平等......
我将从创建几个通用过程开始,我们可以使用它们来更好地描述问题的解决方案。
与其他解决方案相比,您会注意到此解决方案不对数据的内部结构做任何假设。此解决方案不关心对象中使用的实际键名。
这意味着我们不会触及任何 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: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}]
明白了!
您将不得不稍微调整此解决方案,因为您没有比较所有对象键。 finalResult
中的对象比 duplicateTestData
中的对象具有更多键,因此有零个 1:1 匹配项。
简单来说,如果 x = {a:1}
与 y = {a:1,b:2}
进行比较,您希望将其视为 "match",只要 x
中的所有 key:values ] 匹配 y
中的所有 key:values
如果我们使用上面的 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
为 undefined
时,这意味着该值的键不存在于 "subset object" 中,因此不需要进行比较
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,...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[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',
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' }
]
// get all finalResult items that do not subsetObjectEqual items in duplicateTestData
var result = finalResult.filter(x=>
duplicateTestData.find(subsetObjectEquals(x)) === undefined)
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>
这里的核心是_.reject()
, which is the opposite of _.filter()
: when passed an object it will use _.matches()
做局部比较
至运行 它对于duplicateTestData 中的每个条目我们可以使用.reduce()
,标准数组函数。我们传入 finalResult 作为 initialValue。方便的是参数顺序正确,所以我们不需要匿名函数! (我真的应该说 lodash 是一个设计非常好的库。)一旦 reduce()
已经 运行 通过了 duplicateTestData 中的所有条目,它将 return 最终过滤结果。
我正在从服务器获取两个对象数组,如下所示:
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);
var res = _.filter(finalResult, function(item) {
return !_.find(duplicateTestData, {
batchId: item.batchId,
licenseId: item.licenseId,
reportDate: item.reportDate
});
});
console.log(res);
你可以使用哈希 table 和 return 一个新的结果集,而不会在迭代时出现拼接数组的问题。
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);
ES6
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' }],
map = duplicateTestData.reduce((r, a) => r.set(getKey(a)), new Map),
result = finalResult.filter(a => !map.has(getKey(a)));
console.log(result);
简单的出路
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' } ]
好的,有效,但这主要是垃圾。它没有完全准确地描述您要进行的比较。它太具体了,一旦你的数据发生变化,它就会崩溃。
继续阅读,我们可以学到一些有趣的东西。
所有(键和值)的对象平等......
我将从创建几个通用过程开始,我们可以使用它们来更好地描述问题的解决方案。
与其他解决方案相比,您会注意到此解决方案不对数据的内部结构做任何假设。此解决方案不关心对象中使用的实际键名。
这意味着我们不会触及任何 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: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}]
明白了!
您将不得不稍微调整此解决方案,因为您没有比较所有对象键。 finalResult
中的对象比 duplicateTestData
中的对象具有更多键,因此有零个 1:1 匹配项。
简单来说,如果 x = {a:1}
与 y = {a:1,b:2}
进行比较,您希望将其视为 "match",只要 x
中的所有 key:values ] 匹配 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
为 undefined
时,这意味着该值的键不存在于 "subset object" 中,因此不需要进行比较
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,...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[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',
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' }
]
// get all finalResult items that do not subsetObjectEqual items in duplicateTestData
var result = finalResult.filter(x=>
duplicateTestData.find(subsetObjectEquals(x)) === undefined)
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>
这里的核心是_.reject()
, which is the opposite of _.filter()
: when passed an object it will use _.matches()
做局部比较
至运行 它对于duplicateTestData 中的每个条目我们可以使用.reduce()
,标准数组函数。我们传入 finalResult 作为 initialValue。方便的是参数顺序正确,所以我们不需要匿名函数! (我真的应该说 lodash 是一个设计非常好的库。)一旦 reduce()
已经 运行 通过了 duplicateTestData 中的所有条目,它将 return 最终过滤结果。