Helpex - Trao đổi & giúp đỡ Đăng nhập
730

Tôi có một cấu trúc dữ liệu lồng nhau chứa các đối tượng và mảng. Làm cách nào tôi có thể trích xuất thông tin, tức là truy cập vào một giá trị cụ thể hoặc nhiều giá trị (hoặc khóa)?

Ví dụ:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

Làm thế nào tôi có thể truy cập vào namemục thứ hai trong items?

730 hữu ích 3 bình luận 461k xem chia sẻ
20 trả lời 20
994

Sơ bộ

JavaScript chỉ có một loại dữ liệu có thể chứa nhiều giá trị: Object . Một mảng là một dạng đối tượng đặc biệt.

(Đồng bằng) Các đối tượng có dạng

{key: value, key: value, ...}

Mảng có hình thức

[value, value, ...]

Cả mảng và đối tượng phơi bày một key -> valuecấu trúc. Các khóa trong một mảng phải là số, trong khi bất kỳ chuỗi nào cũng có thể được sử dụng làm khóa trong các đối tượng. Các cặp khóa-giá trị cũng được gọi là "thuộc tính" .

Các thuộc tính có thể được truy cập bằng cách sử dụng ký hiệu chấm

const value = obj.someProperty;

hoặc ký hiệu ngoặc , nếu tên thuộc tính sẽ không phải là tên định danh JavaScript hợp lệ [spec] hoặc tên là giá trị của biến:

// the space is not a valid character in identifier names
const value = obj["some Property"];

// property name as variable
const name = "some Property";
const value = obj[name];

Vì lý do đó, các phần tử mảng chỉ có thể được truy cập bằng cách sử dụng ký hiệu ngoặc:

const value = arr[5]; // arr.5 would be a syntax error

// property name / index as variable
const x = 5;
const value = arr[x];

Đợi ... còn JSON thì sao?

JSON là một biểu diễn văn bản của dữ liệu, giống như XML, YAML, CSV và các thứ khác. Để làm việc với dữ liệu đó, trước tiên, nó phải được chuyển đổi thành các loại dữ liệu JavaScript, tức là mảng và đối tượng (và cách làm việc với những dữ liệu vừa được giải thích). Làm cách nào để phân tích JSON được giải thích trong câu hỏi Phân tích JSON trong JavaScript? .

Đọc thêm tài liệu

Cách truy cập mảng và đối tượng là kiến ​​thức cơ bản về JavaScript và do đó, nên đọc Hướng dẫn JavaScript MDN , đặc biệt là các phần



Truy cập cấu trúc dữ liệu lồng nhau

Cấu trúc dữ liệu lồng nhau là một mảng hoặc đối tượng tham chiếu đến các mảng hoặc đối tượng khác, tức là các giá trị của nó là mảng hoặc đối tượng. Các cấu trúc như vậy có thể được truy cập bằng cách áp dụng liên tục dấu chấm hoặc dấu ngoặc.

Đây là một ví dụ:

const data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

Giả sử chúng ta muốn truy cập vào namemục thứ hai.

Đây là cách chúng ta có thể làm từng bước một:

Như chúng ta có thể thấy datalà một đối tượng, do đó chúng ta có thể truy cập các thuộc tính của nó bằng cách sử dụng ký hiệu chấm. Các itemstài sản được truy cập như sau:

data.items

Giá trị là một mảng, để truy cập phần tử thứ hai của nó, chúng ta phải sử dụng ký hiệu ngoặc:

data.items[1]

Giá trị này là một đối tượng và chúng tôi sử dụng ký hiệu chấm một lần nữa để truy cập vào thuộc nametính. Vì vậy, cuối cùng chúng tôi nhận được:

const item_name = data.items[1].name;

Ngoài ra, chúng tôi có thể đã sử dụng ký hiệu dấu ngoặc cho bất kỳ thuộc tính nào, đặc biệt nếu tên chứa các ký tự sẽ làm cho nó không hợp lệ cho việc sử dụng ký hiệu dấu chấm:

const item_name = data['items'][1]['name'];

Tôi đang cố gắng truy cập vào một tài sản nhưng tôi chỉ nhận undefinedlại?

Hầu hết thời gian khi bạn nhận được undefined, đối tượng / mảng đơn giản là không có thuộc tính với tên đó.

const foo = {bar: {baz: 42}};
console.log(foo.baz); // undefined

Sử dụng console.loghoặc console.dirvà kiểm tra cấu trúc của đối tượng / mảng. Thuộc tính bạn đang cố truy cập có thể thực sự được xác định trên một đối tượng / mảng lồng nhau.

console.log(foo.bar.baz); // 42

Điều gì xảy ra nếu tên tài sản là động và tôi không biết chúng trước?

Nếu tên thuộc tính không xác định hoặc chúng tôi muốn truy cập tất cả các thuộc tính của một đối tượng / phần tử của một mảng, chúng ta có thể sử dụng vòng lặp for...in [MDN] cho các đối tượng và vòng lặp for [MDN] cho các mảng để lặp lại trên tất cả các thuộc tính / phần tử.

Các đối tượng

Để lặp lại tất cả các thuộc tính của data, chúng ta có thể lặp lại đối tượng như vậy:

for (const prop in data) {
    // `prop` contains the name of each property, i.e. `'code'` or `'items'`
    // consequently, `data[prop]` refers to the value of each property, i.e.
    // either `42` or the array
}

Tùy thuộc vào nơi đối tượng đến từ (và những gì bạn muốn làm), bạn có thể phải kiểm tra trong mỗi lần lặp xem liệu thuộc tính đó có thực sự là một thuộc tính của đối tượng hay đó là một thuộc tính được thừa kế. Bạn có thể làm điều này với Object#hasOwnProperty [MDN] .

Thay thế cho for...inbằng hasOwnProperty, bạn có thể sử dụng Object.keys [MDN] để lấy một mảng các tên thuộc tính :

Object.keys(data).forEach(function(prop) {
  // `prop` is the property name
  // `data[prop]` is the property value
});

Mảng

Để lặp lại tất cả các phần tử của data.items mảng , chúng tôi sử dụng một forvòng lặp:

for(let i = 0, l = data.items.length; i < l; i++) {
    // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration
    // we can access the next element in the array with `data.items[i]`, example:
    // 
    // var obj = data.items[i];
    // 
    // Since each element is an object (in our example),
    // we can now access the objects properties with `obj.id` and `obj.name`. 
    // We could also use `data.items[i].id`.
}

Người ta cũng có thể sử dụng for...inđể lặp lại trên các mảng, nhưng có những lý do tại sao điều này nên tránh: Tại sao 'for (var item in list)' với các mảng được coi là thực hành xấu trong JavaScript? .

Với sự hỗ trợ trình duyệt ngày càng tăng của ECMAScript 5, phương thức mảng forEach [MDN] cũng trở thành một thay thế thú vị:

data.items.forEach(function(value, index, array) {
    // The callback is executed for each element in the array.
    // `value` is the element itself (equivalent to `array[index]`)
    // `index` will be the index of the element in the array
    // `array` is a reference to the array itself (i.e. `data.items` in this case)
}); 

Trong các môi trường hỗ trợ ES2015 (ES6), bạn cũng có thể sử dụng vòng lặp [MDN] , không chỉ hoạt động cho các mảng, mà còn cho bất kỳ lần lặp nào :for...of

for (const item of data.items) {
   // `item` is the array element, **not** the index
}

Trong mỗi lần lặp, for...oftrực tiếp cung cấp cho chúng ta phần tử tiếp theo của lần lặp, không có "chỉ mục" để truy cập hoặc sử dụng.


Điều gì xảy ra nếu tôi không biết "độ sâu" của cấu trúc dữ liệu?

Ngoài các khóa không xác định, "độ sâu" của cấu trúc dữ liệu (nghĩa là có bao nhiêu đối tượng lồng nhau), có thể cũng không xác định được. Làm thế nào để truy cập các thuộc tính lồng nhau sâu thường phụ thuộc vào cấu trúc dữ liệu chính xác.

Nhưng nếu cấu trúc dữ liệu chứa các mẫu lặp lại, ví dụ: biểu diễn của cây nhị phân, giải pháp thường bao gồm để truy cập đệ quy [Wikipedia] từng cấp của cấu trúc dữ liệu.

Dưới đây là một ví dụ để có được nút lá đầu tiên của cây nhị phân:

function getLeaf(node) {
    if (node.leftChild) {
        return getLeaf(node.leftChild); // <- recursive call
    }
    else if (node.rightChild) {
        return getLeaf(node.rightChild); // <- recursive call
    }
    else { // node must be a leaf node
        return node;
    }
}

const first_leaf = getLeaf(root);

Hiển thị đoạn mã

Một cách chung hơn để truy cập cấu trúc dữ liệu lồng nhau với các khóa và độ sâu không xác định là kiểm tra loại giá trị và hành động tương ứng.

Dưới đây là một ví dụ bổ sung tất cả các giá trị nguyên thủy bên trong cấu trúc dữ liệu lồng nhau vào một mảng (giả sử nó không chứa bất kỳ hàm nào). Nếu chúng ta gặp một đối tượng (hoặc mảng), chúng ta chỉ cần gọi toArraylại vào giá trị đó (cuộc gọi đệ quy).

function toArray(obj) {
    const result = [];
    for (const prop in obj) {
        const value = obj[prop];
        if (typeof value === 'object') {
            result.push(toArray(value)); // <- recursive call
        }
        else {
            result.push(value);
        }
    }
    return result;
}

Hiển thị đoạn mã



Người giúp việc

Do cấu trúc của một đối tượng hoặc mảng phức tạp không nhất thiết phải rõ ràng, chúng ta có thể kiểm tra giá trị ở mỗi bước để quyết định cách di chuyển xa hơn. console.log [MDN]console.dir [MDN] giúp chúng tôi thực hiện việc này. Ví dụ: (đầu ra của bảng điều khiển Chrome):

> console.log(data.items)
 [ Object, Object ]

Ở đây chúng ta thấy rằng đó data.itemslà một mảng có hai phần tử là cả hai đối tượng. Trong bảng điều khiển Chrome, các đối tượng thậm chí có thể được mở rộng và kiểm tra ngay lập tức.

> console.log(data.items[1])
  Object
     id: 2
     name: "bar"
     __proto__: Object

Điều này cho chúng ta biết đó data.items[1]là một đối tượng và sau khi mở rộng nó, chúng ta thấy rằng nó có ba thuộc tính id, name__proto__. Cái sau là một thuộc tính nội bộ được sử dụng cho chuỗi nguyên mẫu của đối tượng. Chuỗi nguyên mẫu và kế thừa nằm ngoài phạm vi cho câu trả lời này, mặc dù.

994 hữu ích 3 bình luận chia sẻ
60

Bạn có thể truy cập nó theo cách này

data.items[1].name

hoặc là

data["items"][1]["name"]

Cả hai cách đều như nhau.

60 hữu ích 2 bình luận chia sẻ
29

Trong trường hợp bạn đang cố gắng truy cập itemtừ cấu trúc ví dụ bằng idhoặc name, mà không biết vị trí của nó trong mảng, cách dễ nhất để làm là sử dụng thư viện underscore.js :

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

_.find(data.items, function(item) {
  return item.id === 2;
});
// Object {id: 2, name: "bar"}

Từ kinh nghiệm của tôi, việc sử dụng các hàm bậc cao hơn thay vì forhoặc for..incác vòng lặp dẫn đến mã dễ lý do hơn và do đó dễ bảo trì hơn.

Chỉ 2 xu của tôi.

29 hữu ích 0 bình luận chia sẻ
19

Đôi khi, truy cập một đối tượng lồng nhau bằng cách sử dụng một chuỗi có thể được mong muốn. Cách tiếp cận đơn giản là cấp độ đầu tiên, ví dụ

var obj = { hello: "world" };
var key = "hello";
alert(obj[key]);//world

Nhưng điều này thường không phải là trường hợp với json phức tạp. Khi json trở nên phức tạp hơn, các phương pháp tìm kiếm giá trị bên trong json cũng trở nên phức tạp. Một cách tiếp cận đệ quy để điều hướng json là tốt nhất và cách đệ quy đó được tận dụng sẽ phụ thuộc vào loại dữ liệu được tìm kiếm. Nếu có các điều kiện liên quan, một tìm kiếm json có thể là một công cụ tốt để sử dụng.

Nếu thuộc tính đang được truy cập đã được biết, nhưng đường dẫn phức tạp, ví dụ trong đối tượng này

var obj = {
 arr: [
    { id: 1, name: "larry" },    
    { id: 2, name: "curly" },
    { id: 3, name: "moe" }
 ]
};

Và bạn biết bạn muốn nhận kết quả đầu tiên của mảng trong đối tượng, có lẽ bạn muốn sử dụng

var moe = obj["arr[0].name"];

Tuy nhiên, điều đó sẽ gây ra một ngoại lệ vì không có thuộc tính của đối tượng có tên đó. Giải pháp để có thể sử dụng điều này sẽ là làm phẳng khía cạnh cây của đối tượng. Điều này có thể được thực hiện đệ quy.

function flatten(obj){
 var root = {};
 (function tree(obj, index){
   var suffix = toString.call(obj) == "[object Array]" ? "]" : "";
   for(var key in obj){
    if(!obj.hasOwnProperty(key))continue;
    root[index+key+suffix] = obj[key];
    if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"[");
    if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+".");   
   }
 })(obj,"");
 return root;
}

Bây giờ, đối tượng phức tạp có thể được làm phẳng

var obj = previous definition;
var flat = flatten(obj);
var moe = flat["arr[0].name"];//moe

Đây là một jsFiddle Demotrong những phương pháp này đang được sử dụng.

19 hữu ích 3 bình luận chia sẻ
16

Các đối tượng và mảng có rất nhiều phương thức tích hợp có thể giúp bạn xử lý dữ liệu.

Lưu ý: trong nhiều ví dụ tôi đang sử dụng các hàm mũi tên . Chúng tương tự như các biểu thức hàm , nhưng chúng liên kết thisgiá trị theo từ vựng.

Object.keys(), Object.values()(ES 2017) và Object.entries()(ES 2017)

Object.keys()trả về một mảng các khóa của đối tượng, Object.values()trả về một mảng các giá trị của đối tượng và Object.entries()trả về một mảng các khóa của đối tượng và các giá trị tương ứng theo định dạng [key, value].

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

console.log(Object.keys(obj)) // ['a', 'b', 'c']
console.log(Object.values(obj)) // [1, 2, 3]
console.log(Object.entries(obj)) // [['a', 1], ['b', 2], ['c', 3]]

Object.entries() với một vòng lặp for và hủy bỏ nhiệm vụ

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`key: ${key}, value: ${value}`)
}

Nó rất thuận tiện để lặp lại kết quả của Object.entries()một vòng lặp forhủy bài tập .

Vòng lặp for cho phép bạn lặp lại các phần tử mảng. Cú pháp là for (const element of array)(chúng ta có thể thay thế constbằng varhoặc let, nhưng tốt hơn là sử dụng constnếu chúng ta không có ý định sửa đổi element).

Phân công cấu trúc cho phép bạn trích xuất các giá trị từ một mảng hoặc một đối tượng và gán chúng cho các biến. Trong trường hợp này const [key, value]có nghĩa là thay vì gán [key, value]mảng cho element, chúng ta gán phần tử đầu tiên của mảng đó keyvà phần tử thứ hai cho value. Nó tương đương với điều này:

for (const element of Object.entries(obj)) {
  const key = element[0]
       ,value = element[1]
}

Như bạn có thể thấy, việc phá hủy làm cho việc này đơn giản hơn rất nhiều.

Array.prototype.every()Array.prototype.some()

Các every()phương thức trả về truenếu hàm callback quy định trả truecho mỗi phần tử của mảng. Các some()phương thức trả về truenếu hàm callback quy định trả truecho một số (ít nhất một) phần tử.

const arr = [1, 2, 3]

// true, because every element is greater than 0
console.log(arr.every(x => x > 0))
// false, because 3^2 is greater than 5
console.log(arr.every(x => Math.pow(x, 2) < 5))
// true, because 2 is even (the remainder from dividing by 2 is 0)
console.log(arr.some(x => x % 2 === 0))
// false, because none of the elements is equal to 5
console.log(arr.some(x => x === 5))

Array.prototype.find()Array.prototype.filter()

Các find()phương thức trả về phần tử đầu tiên thỏa mãn hàm gọi lại được cung cấp. Các filter()phương thức trả về một mảng của tất cả các yếu tố đó đáp ứng các chức năng gọi lại cung cấp.

const arr = [1, 2, 3]

// 2, because 2^2 !== 2
console.log(arr.find(x => x !== Math.pow(x, 2)))
// 1, because it's the first element
console.log(arr.find(x => true))
// undefined, because none of the elements equals 7
console.log(arr.find(x => x === 7))

// [2, 3], because these elements are greater than 1
console.log(arr.filter(x => x > 1))
// [1, 2, 3], because the function returns true for all elements
console.log(arr.filter(x => true))
// [], because none of the elements equals neither 6 nor 7
console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

Các map()phương thức trả về một mảng với kết quả của cách gọi một hàm callback được cung cấp trên các phần tử mảng.

const arr = [1, 2, 3]

console.log(arr.map(x => x + 1)) // [2, 3, 4]
console.log(arr.map(x => String.fromCharCode(96 + x))) // ['a', 'b', 'c']
console.log(arr.map(x => x)) // [1, 2, 3] (no-op)
console.log(arr.map(x => Math.pow(x, 2))) // [1, 4, 9]
console.log(arr.map(String)) // ['1', '2', '3']

Array.prototype.reduce()

Các reduce()phương pháp làm giảm một mảng đến một giá trị duy nhất bằng cách gọi hàm callback được cung cấp với hai yếu tố.

const arr = [1, 2, 3]

// Sum of array elements.
console.log(arr.reduce((a, b) => a + b)) // 6
// The largest number in the array.
console.log(arr.reduce((a, b) => a > b ? a : b)) // 3

Các reduce()phương pháp có một tham số tùy chọn thứ hai, đó là giá trị ban đầu. Điều này rất hữu ích khi mảng mà bạn gọi reduce()có thể có 0 hoặc một phần tử. Ví dụ: nếu chúng ta muốn tạo một hàm sum()lấy một mảng làm đối số và trả về tổng của tất cả các phần tử, chúng ta có thể viết nó như thế:

const sum = arr => arr.reduce((a, b) => a + b, 0)

console.log(sum([]))     // 0
console.log(sum([4]))    // 4
console.log(sum([2, 5])) // 7

16 hữu ích 0 bình luận chia sẻ
10

Câu hỏi này khá cũ, vì vậy là một bản cập nhật đương đại. Với sự khởi đầu của ES2015, có những lựa chọn thay thế để có được dữ liệu bạn yêu cầu. Hiện tại có một tính năng gọi là phá hủy đối tượng để truy cập các đối tượng lồng nhau.

const data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

const {
  items: [, {
    name: secondName
  }]
} = data;

console.log(secondName);

Ví dụ trên tạo ra một biến được gọi secondNametừ namekhóa từ một mảng được gọi items, cô đơn ,nói bỏ qua đối tượng đầu tiên trong mảng.

Đáng chú ý là nó có thể quá mức cần thiết cho ví dụ này, vì tích lũy mảng đơn giản dễ đọc hơn, nhưng nó có ích khi phá vỡ các đối tượng nói chung.

Đây là phần giới thiệu rất ngắn gọn cho trường hợp sử dụng cụ thể của bạn, việc phá hủy có thể là một cú pháp bất thường để làm quen lúc đầu. Tôi khuyên bạn nên đọc tài liệu Phân công hủy cấu trúc của Mozilla để tìm hiểu thêm.

10 hữu ích 0 bình luận chia sẻ
8

Sử dụng JSONPath sẽ là một trong những giải pháp linh hoạt nhất nếu bạn muốn bao gồm thư viện: https://github.com/s3u/JSONPath (nút và trình duyệt)

Đối với trường hợp sử dụng của bạn, đường dẫn json sẽ là:

$..items[1].name

vì thế:

var secondName = jsonPath.eval(data, "$..items[1].name");
8 hữu ích 1 bình luận chia sẻ
8

Để truy cập một thuộc tính lồng nhau, bạn cần chỉ định tên của nó và sau đó tìm kiếm thông qua đối tượng.

Nếu bạn đã biết đường dẫn chính xác, thì bạn có thể mã hóa nó trong tập lệnh của mình như sau:

data['items'][1]['name']

những thứ này cũng hoạt động -

data.items[1].name
data['items'][1].name
data.items[1]['name']

Khi bạn không biết tên chính xác trước khi sử dụng, hoặc người dùng là người cung cấp tên cho bạn. Sau đó, tự động tìm kiếm thông qua cấu trúc dữ liệu được yêu cầu. Một số gợi ý ở đây rằng tìm kiếm có thể được thực hiện bằng cách sử dụng một forvòng lặp, nhưng có một cách rất đơn giản để đi qua một đường dẫn bằng cách sử dụng Array.reduce.

const data = { code: 42, items: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] }
const path = [ 'items', '1', 'name']
let result = path.reduce((a,v) => a[v], data)

Đường dẫn là một cách để nói: Đầu tiên lấy đối tượng bằng khóa items, điều này xảy ra là một mảng. Sau đó lấy 1phần tử -st (0 mảng chỉ mục). Lần cuối lấy đối tượng có khóa nametrong phần tử mảng đó, đó là chuỗi bar.

Nếu bạn có một con đường rất dài, bạn thậm chí có thể sử dụng String.splitđể làm cho tất cả những điều này dễ dàng hơn -

'items.1.name'.split('.').reduce((a,v) => a[v], data)

Đây chỉ là JavaScript đơn giản, không sử dụng bất kỳ thư viện bên thứ ba nào như jQuery hoặc lodash.

8 hữu ích 0 bình luận chia sẻ
7

Tôi thích JQuery hơn. Nó sạch hơn và dễ đọc.

 $.each($.parseJSON(data), function (key, value) {
    alert(value.<propertyname>);
});

7 hữu ích 0 bình luận chia sẻ
6

Bạn có thể sử dụng lodash _getchức năng:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// => 3
6 hữu ích 0 bình luận chia sẻ
5

Nếu bạn đang tìm kiếm một hoặc nhiều đối tượng đáp ứng các tiêu chí nhất định, bạn có một vài tùy chọn sử dụng truy vấn-js

//will return all elements with an id larger than 1
data.items.where(function(e){return e.id > 1;});
//will return the first element with an id larger than 1
data.items.first(function(e){return e.id > 1;});
//will return the first element with an id larger than 1 
//or the second argument if non are found
data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

Ngoài ra còn có một singlesingleOrDefaulthọ làm việc rất giống firstfirstOrDefaulttương ứng. Sự khác biệt duy nhất là họ sẽ ném nếu tìm thấy nhiều hơn một trận đấu.

để giải thích thêm về truy vấn-js, bạn có thể bắt đầu với bài đăng này

5 hữu ích 1 bình luận chia sẻ
4

The Underscore js Way

Đó là một thư viện JavaScript cung cấp toàn bộ các trình functional programmingtrợ giúp hữu ích mà không mở rộng bất kỳ đối tượng tích hợp nào.

Dung dịch:

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'foo'
  }, {
    id: 2,
    name: 'bar'
  }]
};

var item = _.findWhere(data.items, {
  id: 2
});
if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}

//using find - 

var item = _.find(data.items, function(item) {
  return item.id === 2;
});

if (!_.isUndefined(item)) {
  console.log('NAME =>', item.name);
}
4 hữu ích 0 bình luận chia sẻ
4

Câu hỏi cũ nhưng như không ai đề cập đến lodash (chỉ gạch dưới).

Trong trường hợp bạn đã sử dụng lodash trong dự án của mình, tôi nghĩ một cách thanh lịch để làm điều này trong một ví dụ phức tạp:

Lựa chọn 1

_.get(response, ['output', 'fund', 'data', '0', 'children', '0', 'group', 'myValue'], '')

giống như:

Lựa chọn 2

response.output.fund.data[0].children[0].group.myValue

Sự khác biệt giữa tùy chọn thứ nhất và thứ hai là trong Opt 1 nếu bạn thiếu một trong các thuộc tính (không xác định) trong đường dẫn bạn không gặp lỗi, nó sẽ trả về cho bạn tham số thứ ba.

Đối với bộ lọc mảng, lodash có _.find()nhưng tôi muốn sử dụng thường xuyên hơn filter(). Nhưng tôi vẫn nghĩ rằng phương pháp trên _.get()là siêu hữu ích khi làm việc với dữ liệu thực sự phức tạp. Tôi đã phải đối mặt với các API thực sự phức tạp trong quá khứ và nó rất tiện dụng!

Tôi hy vọng nó có thể hữu ích cho những ai đang tìm kiếm các tùy chọn để thao tác dữ liệu thực sự phức tạp mà tiêu đề ngụ ý.

4 hữu ích 0 bình luận chia sẻ
4
var ourStorage = {


"desk":    {
    "drawer": "stapler"
  },
"cabinet": {
    "top drawer": { 
      "folder1": "a file",
      "folder2": "secrets"
    },
    "bottom drawer": "soda"
  }
};
ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

hoặc là

//parent.subParent.subsubParent["almost there"]["final property"]

Về cơ bản, sử dụng một dấu chấm giữa mỗi hậu duệ mở ra bên dưới nó và khi bạn có tên đối tượng được tạo từ hai chuỗi, bạn phải sử dụng ký hiệu ["obj Name"]. Nếu không, chỉ cần một dấu chấm là đủ;

Nguồn: https://learn.freecodecamp.org/javascript-alerskyms-and-data-strucenses/basic-javascript/accessing-nested-objects

để thêm vào điều này, việc truy cập Mảng lồng nhau sẽ xảy ra như vậy:

var ourPets = [
  {
    animalType: "cat",
    names: [
      "Meowzer",
      "Fluffy",
      "Kit-Cat"
    ]
  },
  {
    animalType: "dog",
    names: [
      "Spot",
      "Bowser",
      "Frankie"
    ]
  }
];
ourPets[0].names[1]; // Outputs "Fluffy"
ourPets[1].names[0]; // Outputs "Spot"

Nguồn: https://learn.freecodecamp.org/javascript-alerskyms-and-data-strucenses/basic-javascript/accessing-nested-arrays/

4 hữu ích 3 bình luận chia sẻ
3

Tôi không nghĩ người hỏi chỉ quan tâm đến một đối tượng lồng nhau ở cấp độ, vì vậy tôi trình bày bản demo sau đây để trình bày cách truy cập vào nút của đối tượng json lồng nhau sâu. Được rồi, hãy tìm nút có id '5'.

var data = {
  code: 42,
  items: [{
    id: 1,
    name: 'aaa',
    items: [{
        id: 3,
        name: 'ccc'
      }, {
        id: 4,
        name: 'ddd'
      }]
    }, {
    id: 2,
    name: 'bbb',
    items: [{
        id: 5,
        name: 'eee'
      }, {
        id: 6,
        name: 'fff'
      }]
    }]
};

var jsonloop = new JSONLoop(data, 'id', 'items');

jsonloop.findNodeById(data, 5, function(err, node) {
  if (err) {
    document.write(err);
  } else {
    document.write(JSON.stringify(node, null, 2));
  }
});
<script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>

3 hữu ích 1 bình luận chia sẻ
3

Truy cập động đối tượng đa cấp.

var obj = {
  name: "salut",
  subobj: {
    subsubobj: {
      names: "I am sub sub obj"
    }
  }
};

var level = "subobj.subsubobj.names";
level = level.split(".");

var currentObjState = obj;

for (var i = 0; i < level.length; i++) {
  currentObjState = currentObjState[level[i]];
}

console.log(currentObjState);

Fiddle làm việc: https://jsfiddle.net/andreitodorut/3mws3kjL/

3 hữu ích 0 bình luận chia sẻ
1

Một cách tiếp cận pythonic, đệ quy và chức năng để làm sáng tỏ các cây JSON tùy ý:

handlers = {
    list:  iterate,
    dict:  delve,
    str:   emit_li,
    float: emit_li,
}

def emit_li(stuff, strong=False):
    emission = '<li><strong>%s</strong></li>' if strong else '<li>%s</li>'
    print(emission % stuff)

def iterate(a_list):
    print('<ul>')
    map(unravel, a_list)
    print('</ul>')

def delve(a_dict):
    print('<ul>')
    for key, value in a_dict.items():
        emit_li(key, strong=True)
        unravel(value)
    print('</ul>')

def unravel(structure):
    h = handlers[type(structure)]
    return h(structure)

unravel(data)

trong đó dữ liệu là danh sách python (được phân tích cú pháp từ chuỗi văn bản JSON):

data = [
    {'data': {'customKey1': 'customValue1',
           'customKey2': {'customSubKey1': {'customSubSubKey1': 'keyvalue'}}},
  'geometry': {'location': {'lat': 37.3860517, 'lng': -122.0838511},
               'viewport': {'northeast': {'lat': 37.4508789,
                                          'lng': -122.0446721},
                            'southwest': {'lat': 37.3567599,
                                          'lng': -122.1178619}}},
  'name': 'Mountain View',
  'scope': 'GOOGLE',
  'types': ['locality', 'political']}
]
1 hữu ích 3 bình luận chia sẻ
1

Hàm grep của jQuery cho phép bạn lọc qua một mảng:

var data = {
    code: 42,
    items: [{
        id: 1,
        name: 'foo'
    }, {
        id: 2,
        name: 'bar'
    }]
};

$.grep(data.items, function(item) {
    if (item.id === 2) {
        console.log(item.id); //console id of item
        console.log(item.name); //console name of item
        console.log(item); //console item object
        return item; //returns item object
    }

});
// Object {id: 2, name: "bar"}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

1 hữu ích 0 bình luận chia sẻ
1

Chỉ trong trường hợp, bất kỳ ai truy cập câu hỏi này vào năm 2017 trở đi và tìm kiếm một cách dễ nhớ , đây là một bài đăng blog công phu về Truy cập các đối tượng lồng nhau trong JavaScript mà không bị xáo trộn bởi

Không thể đọc thuộc tính 'foo' của lỗi không xác định

1. Mẫu truy cập đối tượng lồng nhau của Oliver Steele

Cách dễ nhất và sạch nhất là sử dụng mẫu truy cập đối tượng lồng nhau của Oliver Steele

const name = ((user || {}).personalInfo || {}).name;

Với ký hiệu này, bạn sẽ không bao giờ gặp phải

Không thể đọc thuộc tính 'tên' của không xác định .

Về cơ bản, bạn kiểm tra xem người dùng có tồn tại không, nếu không, bạn sẽ tạo một đối tượng trống khi đang di chuyển. Bằng cách này, khóa cấp tiếp theo sẽ luôn được truy cập từ một đối tượng tồn tại hoặc một đối tượng trống , nhưng không bao giờ từ không xác định.

2. Truy cập các đối tượng lồng nhau bằng cách sử dụng Array Giảm

Để có thể truy cập các mảng lồng nhau, bạn có thể viết mảng giảm của riêng bạn.

const getNestedObject = (nestedObj, pathArr) => {
    return pathArr.reduce((obj, key) =>
        (obj && obj[key] !== 'undefined') ? obj[key] : undefined, nestedObj);
}

// pass in your object structure as array elements
const name = getNestedObject(user, ['personalInfo', 'name']);

// to access nested array, just pass in array index as an element the path array.
const city = getNestedObject(user, ['personalInfo', 'addresses', 0, 'city']);
// this will return the city from the first address item.

Ngoài ra còn có một loại tuyệt vời xử lý typy thư viện tối thiểu mà làm tất cả điều này cho bạn.

1 hữu ích 5 bình luận chia sẻ
0

Của tôi stringjsonđến từ tệp PHP nhưng vẫn còn, tôi chỉ ra ở đây trong var. Khi tôi trực tiếp đưa json của tôi vào objnó sẽ không có gì cho thấy đó là lý do tại sao tôi đặt tệp json của mình là

var obj=JSON.parse(stringjson); Vì vậy, sau đó tôi nhận được messageobj và hiển thị trong hộp cảnh báo, sau đó tôi nhận được datađó là mảng json và lưu trữ trong một biến ArrObjsau đó tôi đọc đối tượng đầu tiên của mảng đó với giá trị khóa như thế nàyArrObj[0].id

     var stringjson={
        "success": true,
        "message": "working",
        "data": [{
                  "id": 1,
                  "name": "foo"
         }]
      };

                var obj=JSON.parse(stringjson);
                var key = "message";
                alert(obj[key]);
                var keyobj = "data";
                var ArrObj =obj[keyobj];

                alert(ArrObj[0].id);
0 hữu ích 1 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ javascript arrays object recursion data-manipulation , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading