2011-04-24 1 views
45

Tôi có một số dữ liệu mà tôi ban đầu được lưu trữ trong một đối tượng Javascript chung chung, với ID như một chìa khóa:Làm thế nào để giữ một đối tượng Javascript/mảng được yêu cầu trong khi vẫn duy trì tra cứu chính?

{ 
    "7": {"id":"7","name":"Hello"}, 
    "3": {"id":"3","name":"World"}, 
    ... 
} 

Tuy nhiên, tôi phát hiện ra rằng các trình duyệt không đảm bảo một trật tự đối tượng cụ thể khi Looping qua chúng, vì vậy trong "3" ở trên sẽ đến trước "7". Tôi đã chuyển sang sử dụng định dạng mảng như sau:

[ 
    {"id":"7","name":"Hello"}, 
    {"id":"3","name":"World"}, 
    ... 
] 

Bây giờ, tôi có thể lặp lại thứ tự đúng nhưng không thể tra cứu nhanh, ví dụ: data["3"] mà không phải lặp qua mảng.

Có cách nào tốt để kết hợp cả hai cách tiếp cận? Tôi thà tránh sử dụng một đối tượng riêng biệt cho mỗi định dạng, bởi vì đối tượng là khá lớn (hàng trăm yếu tố).

+5

thể trùng lặp của [? Cấu trúc dữ liệu Javascript cho tra cứu nhanh và ra lệnh lặp] (http://stackoverflow.com/questions/3549894/javascript-data-structure-for-fast-lookup-and-ordered-looping) –

+0

Không chắc chắn có một cách tốt hơn để đạt được điều này hơn là câu trả lời tôi đã liên kết đến. Nó phá vỡ mục tiêu của bạn để tránh các đối tượng riêng biệt cho mỗi - nhưng tôi muốn biết một cách tốt hơn! :) –

Trả lời

61

Tôi cũng đã gặp phải vấn đề này. Một giải pháp là giữ một dãy các khóa được sắp xếp ngoài đối tượng gốc.

var objects = { 
    "7": {"id":"7","name":"Hello"}, 
    "3": {"id":"3","name":"World"}, 
    ... 
} 
var order = [ "3", "7", ... ]; 

Bây giờ nếu bạn muốn phần tử thứ hai bạn có thể làm tra cứu này:

var second_object = objects[order[1]]; 

Tiêu chuẩn ECMA không nói bất cứ điều gì về thứ tự của các yếu tố trong một đối tượng. Và cụ thể là Chrome sắp xếp lại các khóa khi chúng trông giống như số. Ví dụ:

var example = { 
    "a": "a", 
    "b": "b", 
    "1": "1", 
    "2": "2" 
}; 

nếu bạn in này trong Chrome sẽ nhận được một cái gì đó như:

{ 
    1: "1", 
    2: "2", 
    "a": "a", 
    "b": "b" 
}; 

Đó là một chút chua .. nhưng cuộc sống.

Bạn cũng có thể sử dụng giải pháp mà Andy liên kết, về cơ bản gói cả hai thứ này lại với nhau trong một đối tượng.

Cách thay thế mà tôi sử dụng rất nhiều là chức năng bản đồ tùy chỉnh cho phép bạn chỉ định thứ tự mà đối tượng được truyền qua. Thông thường, bạn sẽ phân loại khi bạn đang in dữ liệu của mình cho người dùng, trong khi bạn lặp lại và tạo các hàng trong bảng của bạn (ví dụ) trình lặp của bạn sẽ chuyển các hàng theo thứ tự mà hàm sắp xếp của bạn chỉ định. Tôi nghĩ đó là một ý tưởng tốt đẹp :)

Chữ ký trông giống như:

function map(object, callback, sort_function); 

Ví dụ sử dụng:

map(object, function (row) { 
    table.add_row(row.header, row.value); 
}, function (key1, key2) { 
    return object[key1] - object[key2]; 
}); 
+0

Ý tưởng tuyệt vời, cảm ơn! Tôi thực sự đã làm ngược lại những gì bạn đề xuất và giữ lưu trữ dữ liệu chính dưới dạng mảng (để lặp tốt hơn), sau đó tôi lưu trữ các chỉ mục mảng trong một đối tượng, được tạo khi đang di chuyển. – DisgruntledGoat

+0

Sẽ không dễ dàng hơn khi chỉ định giá trị cho các chỉ số với vòng lặp bình thường (var i; i MJB