TypeScript, Looping thông qua một từ điển


184

Trong mã của tôi, tôi có một vài từ điển (như được đề xuất ở đây ) là String được lập chỉ mục. Do đây là một loại ngẫu hứng, tôi đã tự hỏi liệu có bất kỳ đề xuất nào về cách tôi có thể lặp qua từng khóa (hoặc giá trị, tất cả tôi cần các khóa cho dù sao). Bất kỳ trợ giúp đánh giá cao!

myDictionary: { [index: string]: any; } = {};

Bạn đã thử for (var key in myDictionary) { }chưa? Trong vòng lặp, bạn sẽ sử dụng keyđể lấy khóa và myDictionary[key]để nhận giá trị
Ian

@Ian Chỉ cần thử điều đó, dường như không hoạt động. Không có lỗi, nhưng không có gì chạy trong tuyên bố
ben657

1
@Ian Ah xin lỗi, một số mã ở nơi khác đã gây rối với nó. Điều đó hoạt động hoàn hảo! Quan tâm để làm cho nó một câu trả lời để tôi có thể chọn nó?
ben657

Câu trả lời:


294

Để lặp qua khóa / giá trị, sử dụng for invòng lặp:

for (let key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}

8
Điều này nói chung không an toàn; nó cần bài kiểm tra hasOwnProperty (như trong câu trả lời của Jamie Stark) hoặc một cái gì đó khác.
Don nở

20
@DonHatch Nói chung nó rất an toàn. Nó không an toàn trong các trường hợp rất cụ thể (như khi bạn bao gồm các thư viện sửa đổi nguyên mẫu không chính xác hoặc sửa đổi nguyên mẫu không chính xác). Tùy thuộc vào nhà phát triển có nên làm mờ mã của họ bằng các kiểm tra rất có thể không cần thiết
Ian

1
@Ian - Suy nghĩ của tôi là tôi sẽ không sử dụng nó mà không có biện pháp bảo vệ bổ sung vì dường như đó là một tai nạn đang chờ xảy ra, ví dụ nếu mã tìm được chức năng tiện ích, và sau đó ai đó chuyển từ chức năng đó không chỉ đơn giản là một từ điển Đối tượng, nhưng một cái gì đó với các thuộc tính bổ sung. Vâng, như bạn nói, tùy thuộc vào nhà phát triển để cân nhắc khả năng và mức độ nghiêm trọng của kịch bản như vậy. Đối với bản thân tôi, cách tiếp cận ít nặng nề nhất về mặt tinh thần là hành xử như thể một kịch bản như vậy được đảm bảo sẽ xảy ra trong mọi trường hợp - ít phải suy nghĩ.
Don nở

5
@Ian Vấn đề là có quá nhiều thư viện sửa đổi nguyên mẫu đối tượng. Có vẻ là một ý tưởng tồi để ủng hộ loại mô hình này khi tồn tại các lựa chọn thay thế đơn giản tốt hơn nhiều, chẳng hạn như Object.keys(target).forEach(key => { let value = target(key); /* Use key, value here */ });. Nếu bạn phải trình bày phương pháp này, ít nhất hãy đề cập đến các rủi ro và các lựa chọn thay thế tốt hơn cho những người chưa biết rõ hơn.
Yona Appletree

8
Chúng tôi đã có es6 và TypeScript. Tại sao vấn đề viết hasOwnProperty mọi lúc vẫn chưa được giải quyết? Ngay cả trong năm 2017 và với tất cả sự chú ý đến JS. Tôi rất thất vọng.
Gherman

168

<ES 2017 :

Object.keys(obj).forEach(key => {
  let value = obj[key];
});

> = ES 2017 :

Object.entries(obj).forEach(
  ([key, value]) => console.log(key, value);
);

Đây là giải pháp tôi đang tìm kiếm vì nó sẽ cho phép tôi sắp xếp các phím trước khi lặp
Andrew

FYI, điều này không được hỗ trợ trên sân chơi TypeScript tại thời điểm này.
Seanny123

1
Xem ở đây cách thực hiện Object.entriesđể hoạt động trong TypeScript
Alex Klaus

Điều này là hoàn hảo
Piyush Choudhary

66

Còn cái này thì sao?

for (let [key, value] of Object.entries(obj)) {
    ...
}

1
Nó yêu cầu lib es2017 trong tsconfig. Xem stackoverflow.com/questions/45422573/ Mạnh
Stéphane

Đây là những gì tôi cần để vượt qua lỗi typcript trên obj [key] "Không có chữ ký chỉ mục ..." bởi vì tôi rõ ràng đặt loại obj của mình là {[key: string]: string} và không muốn sử dụng {[key: chuỗi]: bất kỳ}. Với điều này, tôi chỉ có thể truy cập 'giá trị'. Cảm ơn
ggedde

Và nếu bạn muốn bỏ qua keytất cả, chỉ cần để trống : [ , value]. (Nhờ bình luận vấn đề này .)
Dominik

50

Có một cảnh báo cho vòng lặp khóa / giá trị mà Ian đã đề cập. Nếu có thể các Đối tượng có thể có các thuộc tính được gắn vào Nguyên mẫu của chúng và khi bạn sử dụng intoán tử, các thuộc tính này sẽ được đưa vào. Vì vậy, bạn sẽ muốn đảm bảo rằng khóa là một thuộc tính của thể hiện của bạn chứ không phải của nguyên mẫu. IE cũ hơn được biết đến vì đã indexof(v)hiển thị như là một chìa khóa.

for (const key in myDictionary) {
    if (myDictionary.hasOwnProperty(key)) {
        let value = myDictionary[key];
    }
}

2
Không cố gắng chia tóc, nhưng vì chúng ta đang nói kịch bản loại, bạn không nên sử dụng phím let thay vì phím var? Rất vui được trả lời cảm ơn.
Luke Dupin

3
Trong thực tế, với phiên bản hiện tại của loại kịch bản lệnh keyvaluecó thể const.
Patrick Desjardins

Tốt hơn hết là đừng gọi hasOwnPropertykiểm tra từ đối tượng đích, thay vào đó hãy làm điều này: ...if (Object.prototype.hasOwnProperty.call(myDictionary, key))...Khác, nếu bạn đang sử dụng eslint với no-prototype-builtinsquy tắc, nó sẽ phát ra lỗi.
sceee

5

Cách ngắn nhất để có được tất cả các giá trị từ điển / đối tượng:

Object.keys(dict).map(k => dict[k]);

0

Để lấy chìa khóa:

function GetDictionaryKeysAsArray(dict: {[key: string]: string;}): string[] {
  let result: string[] = [];
  Object.keys(dict).map((key) =>
    result.push(key),
  );
  return result;
}

0

Ians Trả lời là tốt, nhưng bạn nên sử dụng const thay vì cho chìa khóa vì nó không bao giờ được cập nhật.

for (const key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.