使用平面JavaScript或使用lodash,最简单的方法是什么(希望lodash有一个函数),我将以下数组进行比较并返回已更改的值:
之前
[
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 32},
{id: 2, name: 'Joe', age: 38}
]
后
[
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 33},
{id: 2, name: 'Joe', age: 38}
]
所以在之前和之后,弗兰克现在已经33岁了,所以我怎么能简单地回复:
{id: 1, name: 'Frank', age: 33}
或者更理想的结果:
{id: 1, age: 33}
修改
由于我的问题得到了很好的答案,我决定在服务器端和客户端测试它们。以下是我使用json-generator生成10 000条记录的json文件后得到的结果:
节点7.1.0 :
David Domain. (Flat JS filter & some): 3.396
Result: { id: 1, name: 'Frank', age: 33 }
Ben Aston (Flat JS nested itteration): 4.359
Result: { age: 33, id: 1 }
Gille Q. (Lodash reduce): 21.335
Result: { id: 1, age: 33 }
Stasovlas. (Lodash differenceBy): 1.442
Result: []
Vignesh Murugan. (Lodash findWhere): 0
Result: _.findWhere is not a function
Firefox 50.0.2 :
David Domain. (Flat JS filter & some): 6.695
Result: { id: 1, name: 'Frank', age: 33 }
Ben Aston (Flat JS nested itteration): 10.594
Result: { age: 33, id: 1 }
Gille Q. (Lodash reduce): 40.085
Result: { id: 1, age: 33 }
Stasovlas. (Lodash differenceBy): 6.499
Result: []
这里需要注意的有趣的事情是,当你处理大量数据时,Lodash差异似乎不起作用,在我放弃之前,我最多只能使用3条记录。
@Vignesh必须与Underscore合作过一段时间,但由于情况发生了变化,我不打算这样做,我们现在使用Lodash。
这是我用来测试的代码,及时用于跟踪执行函数所花费的时间,然后循环1000次以获得执行函数的总时间1000次然后除以1000以获得平均数量执行该功能的时间(以毫秒为单位):
var fs = require('fs');
var timely = require('timely');
var _ = require('lodash');
// Ben Aston
var ben_aston = function (a, b) {
return a.reduce((p,c,i)=>{
var diff = objDiff(c, b[i]);
diff && p.push(diff);
return p;
}, [])
}
function objDiff(a, b) {
var diff = Object.keys(a).reduce((p,c,i)=>{
if (a[c] === b[c]) {
return p;
}
p[c] = b[c];
return p;
}, {});
if (!Object.keys(diff).length) {
return;
}
diff.id = a.id;
return diff;
}
var ben_astonT = timely(ben_aston);
// Gille Q.
var gille_q = function (before, after) {
return _.reduce(before, function(result, value, key) {
return _.isEqual(value, after[key]) ?
result : result.concat({id: after[key].id, age: after[key].age});
}, []);
}
var gille_qT = timely(gille_q);
// David Domain
var david_domain = function (before, after) {
return after.filter( function( p, idx ) {
return Object.keys(p).some( function( prop ) {
return p[prop] !== before[idx][prop];
})
})
}
var david_domainT = timely(david_domain);
// Stasovlas
var stasovlas = function (before, after) {
return _.differenceBy(after, before, 'age');
}
var stasovlasT = timely(stasovlas);
// Vignesh Murugan
var vignesh_murugan = function (before, after) {
before.forEach((current) => {
var after = _.findWhere(after,{id : current.id});
if(!_.isEqual(after , current)) {
return _.pick(after,"id","name");
}
});
}
var vignesh_muruganT = timely(vignesh_murugan);
// Load the data
var before = JSON.parse(fs.readFileSync('./before.json', 'utf8'));
var after = JSON.parse(fs.readFileSync('./after.json', 'utf8'));
// Open average tracking
var ben_aston_ave = 0,
gille_q_ave = 0,
david_domain_ave = 0,
stasovlas_ave = 0,
vignesh_murugan_ave = 0;
// Do test
for (i = 0; i < 1000; i++) {
// Ben Aston
ben_astonT(before, after);
ben_aston_ave += ben_astonT.time;
// Gille Q.
gille_qT(before, after);
gille_q_ave += gille_qT.time;
// David Domain
david_domainT(before, after);
david_domain_ave += david_domainT.time;
// Stasovlas
stasovlasT(before, after);
stasovlas_ave += stasovlasT.time;
// Vignesh Murugan
// vignesh_muruganT(before, after);
// vignesh_murugan_ave += vignesh_muruganT.time;
}
// Calc averages
ben_aston_ave = ben_aston_ave / 1000;
gille_q_ave = gille_q_ave / 1000;
david_domain_ave = david_domain_ave / 1000;
stasovlas_ave = stasovlas_ave / 1000;
vignesh_murugan_ave = vignesh_murugan_ave / 1000;
console.log('David Domain. (Flat JS filter & some): '+david_domain_ave);
console.log('Result: { id: 1, name: \'Frank\', age: 33 }');
console.log('Ben Aston (Flat JS nested itteration): '+ben_aston_ave);
console.log('Result: { age: 33, id: 1 }');
console.log('Gille Q. (Lodash reduce): '+gille_q_ave);
console.log('Result: { id: 1, age: 33 }');
console.log('Stasovlas. (Lodash differenceBy): '+stasovlas_ave);
console.log('Result: []');
console.log('Vignesh Murugan. (Lodash findWhere): '+vignesh_murugan_ave);
console.log('Result: _.findWhere is not a function');
答案 0 :(得分:3)
var res = _.differenceBy(after, before, 'age');
答案 1 :(得分:1)
您可以将Array.filter
与Array.some
一起使用,这会为您提供包含更改项目的新数组。
也许是这样的:
var before = [
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 32},
{id: 2, name: 'Joe', age: 38}
]
var after = [
{id: 0, name: 'Bobb', age: 27},
{id: 1, name: 'Frank', age: 33},
{id: 2, name: 'Joe', age: 38}
]
var changed = after.filter( function( p, idx ) {
return Object.keys(p).some( function( prop ) {
return p[prop] !== before[idx][prop];
})
})
console.log(changed)
.as-console-wrapper {
max-height: 100% !important;
}
答案 2 :(得分:1)
你也可以使用lodash reduce方法进行比较,这是我为你的例子做的代码,它返回你想要的jsfiddle:
https://jsfiddle.net/7rf9bphL/1/
var a = [
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 32},
{id: 2, name: 'Joe', age: 38}];
var b = [
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 33},
{id: 2, name: 'Joe', age: 38}];
var result = _.reduce(a, function(result, value, key) {
return _.isEqual(value, b[key]) ?
result : result.concat({id: b[key].id, age: b[key].age});
}, []);
console.log("result", result);
答案 3 :(得分:1)
假设数组索引保持不变:
function diff(a, b) {
return a.reduce((p,c,i)=>{
var diff = objDiff(c, b[i]);
diff && p.push(diff);
return p;
}, [])
}
function objDiff(a, b) {
var diff = Object.keys(a).reduce((p,c,i)=>{
if (a[c] === b[c]) {
return p;
}
p[c] = b[c];
return p;
}, {});
if (!Object.keys(diff).length) {
return;
}
diff.id = a.id;
return diff;
}
const before = [{
id: 0, name: 'Bob', age: 27 }, {
id: 1, name: 'Frank', age: 32 }, {
id: 2, name: 'Joe', age: 38 }]
const after = [{
id: 0, name: 'Bob', age: 27 }, {
id: 1, name: 'Frank', age: 33 }, {
id: 2, name: 'Joe', age: 38 }];
console.log(diff(before, after));
&#13;
答案 4 :(得分:0)
我尝试使用下划线并且工作正常
var x = [
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 32},
{id: 2, name: 'Joe', age: 38}
]
var y = [
{id: 0, name: 'Bob', age: 27},
{id: 1, name: 'Frank', age: 33},
{id: 2, name: 'Joe', age: 38}
]
x.forEach((current) => {
var after = _.findWhere(y,{id : current.id})
if(!_.isEqual(after , current)){
console.log(_.pick(after,"id","name"))
}
})
这是Lodash解决方案
var difference = [];
x.forEach((current) => {
var after = _.find(y,{id : current.id})
if(!_.isEqual(after , current)){
difference.push(_.pick(after,"id","name"))
}
})
console.log(difference)