2016-02-03 5 views
-3

Я НЕ ХОЧУ ТОЛЬКО УДАЛИТЬ ДУБЛИРОВАННЫЙ. Я хочу, чтобы объединить дублируется, а затем удалитьКак объединить дублированные элементы в массиве javascript?

это мой тест массив:

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

и результат должен быть таким:

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

поток следующая> У меня есть элементы, которые могут быть дублированы , если идентификаторы элемента равны другим, я имею в виду, что если идентификатор дублируется, то TEXT fild должен быть объединен в один, а дублированный должен быть удален и должен оставаться уникальным с текстовым полем, например. text: "[text1] [text2] [text3] [text4]" это мой старый вопрос Merge duplicated items in array, но письменные ответы работают только для двух дубликатов.

этот код, что я пытаюсь, но это работает только 2 дубликатов, возможно, я 3 или более дублируют этот код не работает

arr.forEach(function(item, idx){ 

    //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) { 

     //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 this duplicate item 
     arr.splice(i, 1); 
     }  
    } 

}); 
+1

Возможный дубликат [Удалить дубликаты из массива JavaScript] (http://stackoverflow.com/questions/9229645/remove-duplicates-from-javascript-array) – Rajesh

+0

Вы только дублировал ваш предыдущий вопрос, не делайте этого. Вместо этого сохраните первоначальный вопрос, добавив подробности, обновив продвижение и предоставив обратную связь. Кроме того, многие ответы там правильные, как отметил @Oxi, попробуйте, прежде чем ожидать «свободного ответа». –

+0

@SebastienDaniel Я отредактировал свой вопрос и добавил свой код, что я пытаюсь –

ответ

0

Обе версии работают с временным объектом для обращения к элементу с id.

in situ версия изменяет массив и удаляет двойные элементы.

Другая версия создает новый массив и добавляет text к соответствующему свойству.

in situ версия.

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

 
while (i < arr.length) { 
 
    if (!reference[arr[i].id]) { 
 
     reference[arr[i].id] = arr[i]; 
 
     i++; 
 
     continue; 
 
    } 
 
    r = reference[arr[i].id]; 
 
    if (r.text[0] !== '[') { 
 
     r.text = '[' + r.text + ']'; 
 
    } 
 
    r.text += ' [' + arr[i].text + ']'; 
 
    arr.splice(i, 1); 
 
} 
 
document.write('<pre>' + JSON.stringify(arr, 0, 4) + '</pre>');

Это решение возвращает новый массив:

var arr = [{ id: 1, text: 'ab' }, { id: 1, text: 'cd' }, { id: 2, text: 'other' }, { id: 3, text: 'afafas' }, { id: 1, text: 'test' }, { id: 4, text: 'asfasfa' }], 
 
    result = arr.reduce(function (r, a) { 
 
     if (!r.obj[a.id]) { 
 
      r.obj[a.id] = { id: a.id, text: '' }; 
 
      r.array.push(r.obj[a.id]); 
 
     } 
 
     if (r.obj[a.id].text === '') { 
 
      r.obj[a.id].text = a.text; 
 
     } else { 
 
      if (r.obj[a.id].text[0] !== '[') { 
 
       r.obj[a.id].text = '[' + r.obj[a.id].text + ']'; 
 
      } 
 
      r.obj[a.id].text += ' [' + a.text + ']'; 
 
     } 
 

 
     return r; 
 
    }, { array: [], obj: {} }).array; 
 

 
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

0

Является ли это то, что вы хотите?

function merge(a) { 
    var newA = []; 

    a.forEach(function(o) { 
     var index; 

     if (newA.some(function(x, i) { 
      index = i; 
      return x.id === o.id; 
     })) { 
      if (!/\[|\]/.test(newA[index].text)) { 
      newA[index].text = newA[index].text.replace(/^(.*)$/g, "[$1]") 
      } 
      newA[index].text += "[" + o.text + "]"; 
      newA[index].text = newA[index].text.replace(/\]\[/g, "] ["); 
     } else { 
      newA.push({ 
      id: o.id, 
      text: o.text.replace(/^(.*)$/g, "[$1]") 
      }); 
     } 
    }); 

    newA.forEach(function(a) { 
    if (!/ /g.test(a.text)) { 
     a.text = a.text.replace(/\[|\]/g, ""); 
    } 
    }); 

    return newA; 
} 
0

В следующем примере, я преобразовал значения объекта, а затем в массив. Если ваш ID может быть строкой, я бы рекомендовал вам использовать объект, а не массив. Это избавит вас от необходимости повторять цикл для получения данных.

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

 
var _temp = {}; 
 
var final = []; 
 
arr.forEach(function(item){ 
 
    if(!_temp[item.id]) 
 
    _temp[item.id] = []; 
 
    _temp[item.id].push(item.text); 
 
}); 
 

 
Object.keys(_temp).forEach(function(k){ 
 
    var val = ""; 
 
    if(_temp[k].length>1){ 
 
    val = "[ " + _temp[k].join(" ] [ ") + " ]"; 
 
    } 
 
    else 
 
    val = _temp[k][0]; 
 
    
 
    final.push({ 
 
    id:k, 
 
    text: val 
 
    }); 
 
}); 
 

 
console.log("Object: ", _temp); 
 
console.log("Array of Objects: ", final)

Смежные вопросы