2014-09-10 15 views
11

Vì vậy, tôi có một mảng của các đối tượng như thế:Update nếu tồn tại hoặc thêm yếu tố mới để mảng các đối tượng - cách thanh lịch trong javascript + lodash

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

uid là id duy nhất của đối tượng trong mảng này. Tôi đang tìm kiếm một cách thanh lịch để sửa đổi đối tượng nếu chúng ta có đối tượng với uid, nhất định hoặc thêm một phần tử mới, nếu được hiển thị uid không tồn tại trong mảng. Tôi tưởng tượng các chức năng để được cư xử như thế trong giao diện điều khiển js:

> 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"} 
] 

cách hiện tại của tôi dường như không phải rất thanh lịch và chức năng:

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

Tôi đang sử dụng lodash, vì vậy tôi đã suy nghĩ về một cái gì đó như sửa đổi _.union với kiểm tra bình đẳng tùy chỉnh.

Trả lời

8

Bạn có thể sử dụng một đối tượng thay vì một mảng:

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

Các phím là các phím số. Bây giờ chức năng của bạn addOrReplace là đơn giản như thế này:

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

CẬP NHẬT

Nó cũng có thể sử dụng một đối tượng như một chỉ số ngoài mảng.
Bằng cách này bạn đã có tra cứu nhanh và cũng là một mảng hoạt động:

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; 
} 

Hãy nhìn vào các jsfiddle-demo (một giải pháp hướng đối tượng bạn sẽ tìm thấy here)

+0

vâng, tôi thích cấu trúc này quá, nhưng một số thư viện tôi sử dụng không ủng hộ điều này. Giống như [Angular typeahead] (https://github.com/angular-ui/bootstrap/tree/master/src/typeahead), nó chỉ có thể đi qua các mảng. – ganqqwerty

+1

Bạn chỉ có thể sử dụng cấu trúc này làm chỉ mục. Bằng cách này bạn đã có tra cứu nhanh và một mảng bổ sung cho những thứ như một mảng là cần thiết. – friedi

1

gì về việc có các chỉ số của mảng giống như uid, như:

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

cách mà bạn có thể chỉ đơn giản là sử dụng

arr[affectedId] = changedObject; 
+0

sẽ hoạt động tốt nếu tôi có bảo đảm rằng uuid luôn là int. Tôi nghĩ đôi khi không phải vậy. Nhưng ngay cả khi tôi đã có bảo đảm này, tôi cảm thấy không thoải mái khi có mảng với các phần tử thiếu như sau: 'arr [2134], arr [2135]', khi arr [0] không tồn tại. – ganqqwerty

+0

@ganqqwerty để insted của mảng cổ điển sử dụng kết hợp một (đối tượng), theo cách này bạn có thể sử dụng các chỉ số không nguyên và không có "lỗ" trong mảng của bạn – Drecker

3

lẽ

_.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

Bài đăng cũ, nhưng tại sao không sử dụng chức năng lọc?

// 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; 
} 

Đây là cách hoạt động của jsfiddle.

Các vấn đề liên quan