2014-04-29 6 views
2

처음에는 간단하게 해결할 수 있지만 어색해하는 바보 같은 문제가 있습니다. ID와 값 :자바 스크립트에서 병합 병합

[ 
    {id: 2, value: 10}, 
    {id: 4, value: 3}, 
    {id: 2, value: 2}, 
    {id: 1, value: 15} 
] 

내가 유사한 ID를 가진 사람의 값을 요약하는 알고리즘을 작성하려는

가 나는 두 가지 속성을 가진 객체의 배열, 각이있다. 내 최종 결과는 병합 된 개체로 새로운 배열이 : 나는 다음을 시도했습니다

[ 
    {id: 2, value: 12}, 
    {id: 4, value: 3}, 
    {id: 1, value: 15} 
] 

,하지만 작동하지 않습니다

var arr = []; 
arr.push({id: 2, visit:10}); 
arr.push({id: 4, visit:3}); 
arr.push({id: 2, visit:2}); 
arr.push({id: 1, visit:15}); 

// Deep copy 
var copy = jQuery.extend(true, [], arr); 
var masterArr = []; 

for (var i = 0; i < arr.length; i++) { 
    var objArr = []; 
    objArr.push(arr[i]); 
     for (var j = copy.length-1; j > -1; j--) { 
     if (arr[i].id === copy[j].id) { 
      var q = copy.splice(j,1); 
     } 
    } 
     masterArr.push(objArr); 
} 

내 계획은 우선 수집했다 별도의 배열 (objArr)에있는 유사한 객체를 합친 다음 최종 배열 (masterArr)에 저장합니다. jquerys를 사용하여 깊은 복사본 (참조가 아닌)을 만들고 역 반복과 스플 라이스를 사용하여 이미 "중복"으로 발견 된 개체를 제거합니다.

이것은 작동하지 않습니다! 그리고 그것은 내 문제를 해결하는 데 매우 효율적인 방법으로 보이지 않습니다. 어떻게하면됩니까? 성과는 최우선 순위가 아니라 오히려 "가지고있는 것이 좋다"!

감사합니다.

+0

올레 프랑크 (Olefrank), 우리 대답이 도움이 되었습니까? – Cerbrus

답변

1

당신은 이런 식으로 작업을 수행 할 수있는 키 문자열이기 때문에 내가 parseInt(key, 10)을 사용하고

// Assuming: 
a = [{id: 2, value: 10}, {id: 4, value: 3}, {id: 2, value: 2}, {id: 1, value: 15}] 

var b = {}, // Temporary variable; 
    c = []; // This will contain the result; 

// Build a id:value object ({1: 15, 2: 12, 4: 3}) 
a.map(function(current){b[current.id] = (b[current.id] || 0) + current.value}); 
for(var key in b){ // Form that into the desired output format. 
    c.push({id: parseInt(key, 10), value: b[key]}); 
} 

console.log(c); 
/* [{id: 1, value: 15}, 
    {id: 2, value: 12}, 
    {id: 4, value: 3}] */ 

, 당신은 아마 그들을 변환 할 것 다시 정수로.

+1

고마워요! 두 가지 제안 모두 작동합니다! – olefrank

1
// First group the data based on id and sum the values 
var temp = data.reduce(function(result, current) { 
    result[current.id] = (result[current.id] || 0) + current.value; 
    return result; 
}, {}); 

// then recreate the objects with proper id and value properties 
var result = []; 
for (var key in temp) { 
    result.push({ 
     id: parseInt(key, 10), 
     value: temp[key] 
    }); 
} 

console.log(result); 

출력

[ { id: 1, value: 15 }, 
    { id: 2, value: 12 }, 
    { id: 4, value: 3 } ] 
1

가장 빠른 방법은 한 번만 Array.prototype.filter()를 사용하여 배열을 통해 루프 :이 부정확 한 값을 포함하는 원래의 배열을 렌더링하지만

var tmp = {}, 
    result = arr.filter(function (el) { 
     if (tmp.hasOwnProperty(el.id)) { 
      tmp[el.id].visit += el.visit; 
      return false; 
     } 
     else { 
      tmp[el.id] = el; 
      return true; 
     } 
    }); 

은 또한, 개체를 다시 사용합니다. 이것이 문제가되는 경우 예제를 수정하여 각 객체 속성을 새 객체에 복사 할 수 있습니다.