TypeScript วนลูปผ่านพจนานุกรม


184

ในรหัสของฉันฉันมีพจนานุกรมสอง (ตามที่แนะนำที่นี่ ) ซึ่งเป็นดัชนีดัชนี เนื่องจากสิ่งนี้เป็นประเภทที่ได้รับการปรับแต่งเล็กน้อยฉันจึงสงสัยว่ามีคำแนะนำใดบ้างเกี่ยวกับวิธีที่ฉันจะสามารถวนลูปผ่านแต่ละคีย์ได้ ความช่วยเหลือใด ๆ ชื่นชม!

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

คุณลอง: for (var key in myDictionary) { }? ในวงคุณจะต้องใช้keyกุญแจและmyDictionary[key]รับค่า
เอียน

@Ian ลองดูสิดูเหมือนจะไม่ทำงาน ไม่มีข้อผิดพลาด แต่ไม่มีอะไรทำงานภายในคำสั่ง
ben657

1
@Ian ขอโทษด้วยรหัสอื่น ๆ ยุ่งกับมัน มันทำงานได้อย่างสมบูรณ์แบบ! สนใจที่จะทำให้เป็นคำตอบเพื่อให้ฉันสามารถเลือกได้หรือไม่
ben657

คำตอบ:


294

ในการวนซ้ำคีย์ / ค่าให้ใช้การfor inวนซ้ำ:

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

8
โดยทั่วไปจะไม่ปลอดภัย มันต้องการการทดสอบ hasOwnProperty (เช่นเดียวกับคำตอบของ Jamie Stark) หรืออย่างอื่น
Don Hatch

20
@ DonHatch จริงๆแล้วมันปลอดภัยโดยทั่วไป มันไม่ปลอดภัยในกรณีที่เฉพาะเจาะจงมาก (เช่นเมื่อคุณรวมไลบรารีที่ปรับเปลี่ยนต้นแบบไม่ถูกต้องหรือดัดแปลงต้นแบบอย่างไม่ถูกต้อง) ขึ้นอยู่กับนักพัฒนาว่าจะขยายโค้ดของพวกเขาด้วยการตรวจสอบที่ไม่จำเป็นหรือไม่
Ian

1
@Ian - ความคิดของฉันคือฉันจะไม่ใช้มันหากไม่มีการป้องกันเพิ่มเติมเนื่องจากดูเหมือนว่าจะเกิดอุบัติเหตุรอตัวอย่างเช่นถ้ารหัสพบว่ามันเข้าสู่ฟังก์ชั่นยูทิลิตี้แล้วมีคนผ่านพจนานุกรมนั่นไม่ใช่แค่ วัตถุ แต่เป็นสิ่งที่มีคุณสมบัติเพิ่มเติม ใช่อย่างที่คุณพูดมันขึ้นอยู่กับนักพัฒนาที่จะชั่งน้ำหนักความน่าจะเป็นและความรุนแรงของสถานการณ์ดังกล่าว สำหรับตัวฉันเองวิธีที่เป็นภาระน้อยที่สุดคือการประพฤติราวกับว่าสถานการณ์ดังกล่าวรับประกันได้ว่าจะเกิดขึ้นในทุกกรณี - น้อยกว่าที่จะคิด
Don Hatch

5
@Ian ปัญหาคือมีไลบรารีมากเกินไปที่ปรับเปลี่ยนต้นแบบวัตถุ ดูเหมือนว่าเป็นความคิดที่ไม่ดีที่จะสนับสนุนรูปแบบประเภทนี้เมื่อมีทางเลือกที่ง่ายกว่าเช่นObject.keys(target).forEach(key => { let value = target(key); /* Use key, value here */ });เดิม หากคุณต้องแสดงวิธีนี้อย่างน้อยก็พูดถึงความเสี่ยงและทางเลือกที่ดีกว่าสำหรับผู้ที่ยังไม่รู้ดีกว่า
Yona Appletree

8
เรามี es6 และ TypeScript แล้ว เหตุใดปัญหาการเขียนจึงมีอยู่ตลอดเวลาจึงไม่ได้รับการแก้ไข แม้แต่ในปี 2560 และด้วยความสนใจ JS ฉันผิดหวังมาก
Gherman

169

<ES 2017 :

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

> = ES 2017 :

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

นี่เป็นวิธีแก้ปัญหาที่ฉันกำลังมองหาเพราะจะช่วยให้ฉันสามารถเรียงลำดับคีย์ก่อนการวนซ้ำ
Andrew

FYI, สิ่งนี้ไม่รองรับบนสนามเด็กเล่นของ TypeScript ในขณะนี้
Seanny123

1
ดูที่นี่วิธีการObject.entriesทำงานใน TypeScript
Alex Klaus

นี่คือที่สมบูรณ์แบบ
Piyush Choudhary

67

แล้วเรื่องนี้ล่ะ

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

1
มันต้องใช้ lib es2017 ใน tsconfig ดูstackoverflow.com/questions/45422573/…
Stéphane

นี่คือสิ่งที่ฉันต้องได้รับในการผ่านข้อผิดพลาดของ typescript ใน obj [กุญแจ] "ไม่มีลายเซ็นดัชนี ... " เพราะฉันกำหนดประเภท obj ของฉันไว้อย่างชัดเจนเป็น {[key: string]: string} และไม่ต้องการใช้ {[key: สตริง]: any} ด้วยสิ่งนี้ฉันสามารถเข้าถึง 'คุณค่า' ได้ ขอบคุณ
ggedde

และถ้าคุณต้องการที่จะไม่สนใจkeyเลยเพียงปล่อยว่างไว้: [ , value]. (ขอบคุณสำหรับความคิดเห็นของปัญหานี้)
Dominik

50

มีข้อแม้หนึ่งข้อสำหรับคีย์ / ค่าวนที่เอียนกล่าวถึง หากเป็นไปได้ว่าวัตถุอาจมีแอตทริบิวต์ที่แนบมากับต้นแบบและเมื่อคุณใช้inโอเปอเรเตอร์คุณสมบัติเหล่านี้จะถูกรวมไว้ ดังนั้นคุณจะต้องตรวจสอบให้แน่ใจว่ากุญแจนั้นเป็นคุณสมบัติของอินสแตนซ์ของคุณไม่ใช่ของต้นแบบ IEs เก่าเป็นที่รู้จักกันสำหรับการมีindexof(v)การแสดงขึ้นเป็นสำคัญ

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

3
ไม่พยายามแยกเส้นผม แต่เนื่องจากเรากำลังพูดถึงสคริปต์ประเภทคุณไม่ควรใช้ปุ่มปล่อยให้แทนแป้นวาร์ คำตอบที่ดีขอบคุณ
Luke Dupin

3
ในความเป็นจริงกับรุ่นปัจจุบันประเภทสคริปต์keyและสามารถvalueconst
Patrick Desjardins

จะดีกว่าถ้าไม่โทรหา hasOwnPropertyเช็คจากวัตถุเป้าหมายแทนที่จะทำสิ่งนี้: ...if (Object.prototype.hasOwnProperty.call(myDictionary, key))...อื่นถ้าคุณใช้ eslint กับno-prototype-builtinsกฎมันจะปล่อยข้อผิดพลาด
sceee

5

วิธีที่สั้นที่สุดในการรับค่าพจนานุกรม / วัตถุทั้งหมด:

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

0

ในการรับกุญแจ:

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

0

Ians Answer เป็นสิ่งที่ดี แต่คุณควรใช้ const แทนที่จะปล่อยให้สำคัญเพราะมันไม่เคยได้รับการปรับปรุง

for (const key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.