2014-09-10 5 views
11

그래서 나는 그와 같은 객체의 배열을 가지고있다. 주어진 uid,으로 오브젝트를 가지고 있거나, 제시된 uid이 배열에 존재하지 않으면 새로운 요소를 추가하면 오브젝트를 수정하는 우아한 방법을 찾고 있습니다. 나는 기능이 JS 콘솔에서 그렇게 행동 할 상상 :업데이트 존재 나 개체의 배열에 새로운 요소를 추가하면 우아한 방법을 자바 스크립트 + lodash

> addOrReplace(arr, {uid: 1, name: 'changed name', description: "changed description"}) 
> arr 
[ 
    {uid: 1, name: "bla", description: "cucu"}, 
    {uid: 2, name: "smth else", description: "cucarecu"}, 
] 
> addOrReplace(arr, {uid: 3, name: 'new element name name', description: "cocoroco"}) 
> arr 
[ 
    {uid: 1, name: "bla", description: "cucu"}, 
    {uid: 2, name: "smth else", description: "cucarecu"}, 
    {uid: 3, name: 'new element name name', description: "cocoroco"} 
] 

내 현재의 방법은 매우 우아하고 기능 될 것 같지 않습니다 : 내가 lodash 사용하고

function addOrReplace (arr, object) { 
    var index = _.findIndex(arr, {'uid' : object.uid}); 
    if (-1 === index) { 
    arr.push(object); 
    } else { 
    arr[index] = object; 
    } 
} 

, 그래서 나는했다 맞춤 평등 검사를 수정 한 _.union과 같은 것을 생각해보십시오.

답변

8

당신은 대신 객체를 사용할 수 있습니다 사용할 수 있습니다 배열 :

var hash = { 
    '1': {uid: 1, name: "bla", description: "cucu"}, 
    '2': {uid: 2, name: "smth else", description: "cucarecu"} 
}; 

키는 uid입니다.

function addOrReplace(hash, object) { 
    hash[object.uid] = object; 
} 

UPDATE

배열에 추가 인덱스 같은 개체를 사용 또한 가능 : 이제 함수 addOrReplace는 다음과 같이 간단하다.

var arr = [], 
    arrIndex = {}; 

addOrReplace({uid: 1, name: "bla", description: "cucu"}); 
addOrReplace({uid: 2, name: "smth else", description: "cucarecu"}); 
addOrReplace({uid: 1, name: "bli", description: "cici"}); 

function addOrReplace(object) { 
    var index = arrIndex[object.uid]; 
    if(index === undefined) { 
     index = arr.length; 
     arrIndex[object.uid] = index; 
    } 
    arr[index] = object; 
} 

jsfiddle-demo 살펴보세요 (객체 지향 솔루션을 당신이 here을 찾을 수 있습니다) 아마

+0

예,이 구조도 마음에 들지만 일부 라이브러리는 사용하지 않습니다. 그것을 지원하십시오. [Angular typeahead] (https://github.com/angular-ui/bootstrap/tree/master/src/typeahead)와 같이 배열 만 이동할 수 있습니다. – ganqqwerty

+1

이 구조는 인덱스로만 사용할 수 있습니다. 이렇게하면 빠른 조회가 가능하며 배열과 같은 항목에 대한 추가 배열이 필요합니다. – friedi

1

uid와 동일한 배열의 인덱스를하는 것에 대한, 어떻습니까?

arr = []; 
arr[1] = {uid: 1, name: "bla", description: "cucu"}; 
arr[2] = {uid: 2, name: "smth else", description: "cucarecu"}; 

그런 식으로 당신은 단지

arr[affectedId] = changedObject; 
+0

은 uuid가 항상 int임을 보증 할 경우 잘 작동합니다. 나는 때때로 그런 경우가 아니라고 생각합니다. 그러나이 보장이 있다고하더라도 arr [0]이 존재하지 않을 때 arr [2134], arr [2135]와 같은 요소가 누락 된 배열을 갖는 것은 불편합니다. – ganqqwerty

+0

@ganqqerty 그래서 고전 배열을 사용하여 연관 객체 (객체)를 사용할 수 있습니다.이 방법을 사용하면 정수가 아닌 인덱스를 사용할 수 있고 배열에 "구멍"이 없습니다. – Drecker

3

:
이 방법 또한 작업 배열을 빠른 조회를 가지고와 한

_.mixin({ 
    mergeById: function mergeById(arr, obj, idProp) { 
     var index = _.findIndex(arr, function (elem) { 
      // double check, since undefined === undefined 
      return typeof elem[idProp] !== "undefined" && elem[idProp] === obj[idProp]; 
     }); 

     if (index > -1) { 
      arr[index] = obj; 
     } else { 
      arr.push(obj); 
     } 

     return arr; 
    } 
}); 

var elem = {uid: 3, name: 'new element name name', description: "cocoroco"}; 

_.mergeById(arr, elem, "uid"); 
3

이전 게시물,하지만 필터 기능을 사용하지 않는 이유는 무엇입니까?

// If you find the index of an existing uid, save its index then delete it 
//  --- after the filter add the new object. 
function addOrReplace(argh, obj) { 
    var index = -1; 
    argh.filter((el, pos) => { 
    if(el.uid == obj.uid) 
     delete argh[index = pos]; 
    return true; 
    }); 

    // put in place, or append to list 
    if(index == -1) 
    argh.push(obj); 
    else 
    argh[index] = obj; 
} 

어떻게 작동하는지 보여주는 jsfiddle입니다.