如何比较和删除JSON数组中的类似行?

时间:2017-12-27 09:53:27

标签: javascript json

我们假设有两个变量:ab。 JavaScript代码应比较两个变量,并通过删除类似数据生成result

  

类似的数据意味着:ab都有值:202,203,204,205。

var a = [{'pID': 200},{'pID': 201},{'pID': 202},{'pID': 203},{'pID': 204},{'pID': 205}];
var b = [{'fID': 202},{'fID': 203},{'fID': 204},{'fID': 205}];
result = [{'ID': 200}, {'ID': 201}];

我该怎么办?这两个变量有一些相似的数据,但键名不同。如果我在命名任何内容方面有任何错误,请纠正我。

  

JSON数组 a 是数据源的主要变量,即它将拥有比JSON数组 b 更多的数据。

感谢。

5 个答案:

答案 0 :(得分:0)

最简单的方法是从对象中获取值,然后使用filter删除重复项

var getVals = ( arr ) => arr.reduce( (a,b) => a.concat( Object.values( b ) ), [] );
var getIntersection = ( a, b ) => a.filter( item => b.indexOf( item ) == -1 );

var aAr = getVals(a); //get the values
var bAr = getVals(b);

var output = aAr.length > bAr.length ? 
         getIntersection(aAr, bAr) : getIntersection(bAr, aAr) ; //which ever array is bigger use that as the first parameter

<强>演示

var a = [{
  'pID': 200
}, {
  'pID': 201
}, {
  'pID': 202
}, {
  'pID': 203
}, {
  'pID': 204
}, {
  'pID': 205
}];
var b = [{
  'fID': 202
}, {
  'fID': 203
}, {
  'fID': 204
}, {
  'fID': 205
}];
var getVals = (arr) => arr.reduce((a, b) => a.concat(Object.values(b)), []);
var getIntersection = (a, b) => a.filter(item => b.indexOf(item) == -1);

var aAr = getVals(a); //get the values
var bAr = getVals(b);
var output = aAr.length > bAr.length ?
  getIntersection(aAr, bAr) : getIntersection(bAr, aAr);

console.log(output);

答案 1 :(得分:0)

您可以加入两个数组并获取值的出现次数,然后使用array#reduce所有计数为1的值。

var a = [{'pID': 200}, {'pID': 201}, {'pID': 202}, {'pID': 203},{'pID': 204}, {'pID': 205}];    
var b = [{'fID': 202}, {'fID': 203}, {'fID': 204}, {'fID': 205}];

var grouped = a.concat(b).reduce((r, v) => {
  var val = Object.values(v)[0];
  r[val] = (r[val] || 0) + 1;
  return r;
},{});

var result = Object.keys(grouped).reduce((r,k) => {
  if(grouped[k] == 1)
    r.push({ID : k});
  return r;
},[]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

您可以使用Array Filter方法过滤掉不需要的(重复的)值。我提出的解决方案,我们首先从b获取所有值,然后过滤掉a中具有相同值的对象。

// data
var a = [{'pID': 200},{'pID': 201},{'pID': 202},{'pID': 203},{'pID': 204},{'pID': 205}];
var b = [{'fID': 202},{'fID': 203},{'fID': 204},{'fID': 205}];

// get the values of b
var bValues = b.map((element) => (element.fID));

// filter out the a element that have values in bValues
var result = a.filter((element) => {
    return (bValues.indexOf(element.pID) === -1);
});
console.log(result);

答案 3 :(得分:0)

我想只需要一个简单的过滤器和地图,首先过滤然后将其映射到结果类型。如您所知,b中的所有项目都会出现在a

a.filter(aIt=>!b.find(bIt=>bIt.fID===aIt.pID)).map(res=>({'ID': res.pID}))

以下是一个工作示例:

&#13;
&#13;
var a = [{'pID': 200},{'pID': 201},{'pID': 202},{'pID': 203},{'pID': 204},{'pID': 205}];
var b = [{'fID': 202},{'fID': 203},{'fID': 204},{'fID': 205}];

var res = a.filter(aIt=>!b.find(bIt=>bIt.fID===aIt.pID)).map(res=>({'ID': res.pID}));

console.log(res);
&#13;
&#13;
&#13;

使用reduce的另一个解决方案将避免额外的map到结果类型。

a.reduce((res, aIt)=>(!b.find(bIt=>bIt.fID===aIt.pID) && !res.push({ID: aIt.pID}) || res), []);

以下是一个工作示例:

&#13;
&#13;
var a = [{'pID': 200},{'pID': 201},{'pID': 202},{'pID': 203},{'pID': 204},{'pID': 205}];
var b = [{'fID': 202},{'fID': 203},{'fID': 204},{'fID': 205}];

var res = a.reduce((res, aIt)=>(!b.find(bIt=>bIt.fID===aIt.pID) && !res.push({ID: aIt.pID})  || res), []);

console.log(res)
&#13;
&#13;
&#13;

注意:要过滤掉,您可以使用some方法,并且相对于find,它将完全返回true或false(与找到的对象或undefined不同)。两者都有效,并且会在需要时中断。

答案 4 :(得分:0)

假设您只想检查以ID结尾的键,您可以使用Set并删除第二个数组的值并使用值构建一个新数组。

&#13;
&#13;
var a = [{ pID: 200 }, { pID: 201 }, { pID: 202 }, { pID: 203 }, { pID: 204 }, { pID: 205 }],
    b = [{ fID: 202 }, { fID: 203 }, { fID: 204 }, { fID: 205 }],
    getValue = o => o[Object.keys(o).find(k => k.endsWith('ID'))],
    s = new Set(a.map(o => getValue(o))),
    result;

b.forEach(o => s.delete(getValue(o)));

result = Array.from(s, ID => ({ ID }));

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;