合并数组中的重复项

时间:2016-01-26 15:03:27

标签: javascript arrays

我有数组,我想合并重复的项目。

var arr = [{
    'id': 1,
    'text': 'ab'
}, {
    'id': 1,
    'text': 'cd'
}, {
    'id': 2,
    'text': 'other'
}, {
    'id': 3,
    'text': 'afafas'
}, {
    'id': 4,
    'text': 'asfasfa'
}];

var work = arr.reduce(function(p, c) {
    var key = c.id;

    p[key].text.push(c.text);
});

console.log(work);

输出必须是这样的:

[{
    'id': 1,
    'text': ["[ab] [cd]"]
}, {
    'id': 2,
    'text': 'other'
}, {
    'id': 3,
    'text': 'afafas'
}, {
    'id': 4,
    'text': 'asfasfa'
}]

以下是我尝试但结果失败的原因:(https://jsfiddle.net/2m7kzkba/

3 个答案:

答案 0 :(得分:0)

您的错误是从reduce函数中返回任何内容。

这是一个有效的代码:

var arr = [
  {'id': 1, 'text': 'ab'},
  {'id': 1, 'text': 'cd'},
  {'id': 2, 'text': 'other'},
  {'id': 3, 'text': 'afafas'},
  {'id': 4, 'text': 'asfasfa'},
  {'id': 1, 'text': 'ededed'}
];

var work = arr.reduce(function(acc, item) {

    // row not existing, nothing about this id registered > add only string
    if(!acc[item.id] || !acc[item.id].text) {
      acc[item.id] = {text: item.text};
    }
    // row already an array > add new with []
    else if(acc[item.id].text instanceof Array) {
      acc[item.id].text.push('[' + item.text + ']'); 
    }
    // row existing > create array with existing string and new one
    else {
      acc[item.id] = {
        text: ['[' + acc[item.id].text + ']', '[' + item.text + ']']
      };
    }

    return acc;
}, {});

plunker

答案 1 :(得分:0)

如果你不反对使用像Underscore这样的实用程序库,那么这样的东西就可以了:

function mergeListOfObjects(arr) {
  function objectID(obj) {
    return obj.id;
  }

  function objectText(obj) {
    return obj.text;
  }

  function mergeObject(id) {
    return {id: id, text: _.map(_.where(arr, {id: id}), objectText) }; 
  }

  return _.map(_.uniq(_.map(arr, objectID)), mergeObject);
}

console.log(mergeListOfObjects(arr));

n.b。这并不能说明您的示例输出无处不在添加了一些额外的括号,'text': ["[ab]", "[cd]"]。我认为您想要的输出更像'text': ["ab", "cd"]

答案 2 :(得分:0)

这是一个使用两个嵌套迭代器的简单方法

我们将遍历数组,看看是否有重复的项目 通过嵌套迭代每个项目。我们标记重复的项目,稍后会删除它们。

Plunker

arr.forEach(function(item, idx){   

  //Do not iterate if it is marked
  if (typeof item.marked !== 'undefined')
        return;

   //Now lets go throug it from the next element
   for (var i = idx + 1; i < arr.length; i++) {

     //Check if the id matches
     if (item.id === arr[i].id) {

        //Mark
        arr[i].marked = true;

        //If the text field is already an array just add the element        
        if (arr[idx].text.constructor === Array) {
            arr[idx].text.push('[' + arr[i].text + ']');   
         }
         else {  //Create an array if not
            arr[idx].text = new Array('[' + arr[idx].text + ']', '[' + arr[i].text + ']');
         }

      }      
   }

 });


//Delete marked items now
for (var i = arr.length - 1; i >= 0; i--) {
   if (typeof arr[i].marked !== 'undefined')
      arr.splice(i, 1);
 }