การใช้จำนวนเต็มเป็นคีย์ในอาร์เรย์ที่เชื่อมโยงใน JavaScript


104

เมื่อฉันสร้างอาร์เรย์ JavaScript ใหม่และใช้จำนวนเต็มเป็นคีย์แต่ละองค์ประกอบของอาร์เรย์นั้นจนถึงจำนวนเต็มจะถูกสร้างขึ้นโดยไม่ได้กำหนดไว้

ตัวอย่างเช่น:

var test = new Array();
test[2300] = 'Some string';
console.log(test);

จะส่งออก 2298 undefined และหนึ่งสตริง 'Some string'

ฉันจะให้ JavaScript ใช้ 2300 เป็นสตริงแทนจำนวนเต็มได้อย่างไรหรือฉันจะป้องกันไม่ให้อินสแตนซ์ดัชนีว่าง 2299 ได้อย่างไร

คำตอบ:


131

ใช้วัตถุตามที่ผู้คนพูด อย่างไรก็ตามโปรดทราบว่าคุณไม่สามารถมีคีย์จำนวนเต็มได้ JavaScript จะแปลงจำนวนเต็มสตริง ผลลัพธ์ต่อไปนี้ 20 ไม่ได้กำหนด:

var test = {}
test[2300] = 20;
console.log(test["2300"]);

12
+1 โปรดทราบว่านี่เป็นความจริงแม้แต่กับ Arrays! ดูstackoverflow.com/questions/1450957/…
bobince

1
@bobince: ภายในแน่นอน อย่างไรก็ตามในทางตรรกะอาร์เรย์มี "คีย์" จำนวนเต็ม
Lightness Races ในวงโคจร

1
โปรดทราบว่าการใช้จำนวนเต็มเป็นคีย์จะเปลี่ยนความยาวของอาร์เรย์ของคุณ แน่นอนคุณควรใช้ Object แทน ฉันแค่ต้องการใช้รหัส facebook เป็นคีย์และ JSON.stringify จะทำให้เครื่องของฉันพัง;)
Krystian

2
@LightnessRacesinOrbit รายละเอียดภายในยังคงรั่วไหลและกัดคุณได้ ดูเวอร์ชันที่เรียบง่ายของสิ่งที่ฉันพบในวันนี้: jsfiddle.net/cincodenada/pseujLex/2มันอาจดูเหมือนสร้างขึ้นเมื่อลดลง แต่เป็นส่วนที่สมเหตุสมผลของสคริปต์ที่ใหญ่กว่า (และมีการสร้างน้อยกว่าเล็กน้อยใน CoffeeScript: jsfiddle.net/ cincodenada / oojr7Ltn / 2 ) รายละเอียดการใช้งานที่ดูเหมือนจะทำให้ฉันเสียค่าใช้จ่ายในการล่าบั๊กในวันนี้
cincodenada

2
บันทึกเล็ก ๆ น้อย ๆ สำหรับตัวเลขที่ไม่ใช่ทั้งหมด: 0.25และมีมติให้สายเดียวกัน.25 "0.25"ดังนั้นถ้าคุณกำลังใช้คีย์เศษส่วนคุณสามารถดึงคุณสมบัติของคีย์ตั้งตัวเลข0.25ใช้0.25, .25, แต่ไม่"0.25" ".25"
Sandy Gifford

35

คุณสามารถใช้วัตถุ:

var test = {}
test[2300] = 'Some string';

16
ยังคงได้รับการคัดเลือกให้เป็นสตริง
drew010

1
@ drew010 ใช่วัตถุของ Javascript อนุญาตให้สร้างดัชนีด้วยสตริงเท่านั้น
Pithikos

22

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

คุณสามารถสร้างวัตถุของคุณ:

var object = {};

และเพิ่มค่าเมื่ออาร์เรย์ทำงาน:

object[1] = value;
object[2] = value;

สิ่งนี้จะทำให้คุณ:

{
  '1': value,
  '2': value
}

หลังจากนั้นคุณสามารถเข้าถึงได้เช่นเดียวกับอาร์เรย์ในภาษาอื่น ๆ เพื่อรับคีย์:

for(key in object)
{
   value = object[key] ;
}

ฉันได้ทดสอบและใช้งานได้จริง


17

หากกรณีการใช้งานกำลังจัดเก็บข้อมูลในคอลเล็กชันECMAScript 6จะจัดเตรียมMapประเภท

การเริ่มต้นจะยากกว่าเท่านั้น

นี่คือตัวอย่าง:

const map = new Map();
map.set(1, "One");
map.set(2, "Two");
map.set(3, "Three");

console.log("=== With Map ===");

for (const [key, value] of map) {
    console.log(`${key}: ${value} (${typeof(key)})`);
}

console.log("=== With Object ===");

const fakeMap = {
    1: "One",
    2: "Two",
    3: "Three"
};

for (const key in fakeMap) {
    console.log(`${key}: ${fakeMap[key]} (${typeof(key)})`);
}

ผลลัพธ์:

=== With Map ===
1: One (number)
2: Two (number)
3: Three (number)
=== With Object ===
1: One (string)
2: Two (string)
3: Three (string)

11

รวบรวมคำตอบอื่น ๆ :

วัตถุ

var test = {};

เมื่อใช้ตัวเลขเป็นคีย์ของคุณสมบัติใหม่ตัวเลขจะเปลี่ยนเป็นสตริง:

test[2300] = 'Some string';
console.log(test['2300']);
// Output: 'Some string'

เมื่อเข้าถึงค่าของคุณสมบัติโดยใช้หมายเลขเดียวกันตัวเลขจะกลายเป็นสตริงอีกครั้ง:

console.log(test[2300]);
// Output: 'Some string'

เมื่อรับกุญแจจากวัตถุพวกเขาจะไม่เปลี่ยนกลับเป็นตัวเลข:

for (var key in test) {
    console.log(typeof key);
}
// Output: 'string'

แผนที่

ECMAScript 6 ช่วยให้การใช้แผนที่วัตถุ (คนเอกสาร , การเปรียบเทียบกับวัตถุ ) หากรหัสของคุณถูกตีความในเครื่องหรือตารางความเข้ากันได้ของ ECMAScript 6มีลักษณะเป็นสีเขียวเพียงพอสำหรับวัตถุประสงค์ของคุณให้พิจารณาใช้แผนที่:

var test = new Map();
test.set(2300, 'Some string');
console.log(test.get(2300));
// Output: 'Some string'

ไม่มีการแปลงประเภทให้ดีขึ้นและแย่ลง:

console.log(test.get('2300'));
// Output: undefined
test.set('2300', 'Very different string');
console.log(test.get(2300));
// Output: 'Some string'

4

ใช้วัตถุแทนอาร์เรย์ อาร์เรย์ใน JavaScript ไม่ใช่อาร์เรย์ที่เชื่อมโยงกัน เป็นวัตถุที่มีเวทมนตร์เกี่ยวข้องกับคุณสมบัติใด ๆ ที่มีชื่อดูเหมือนเลขจำนวนเต็ม เวทมนตร์นั้นไม่ใช่สิ่งที่คุณต้องการหากคุณไม่ได้ใช้มันเป็นโครงสร้างแบบอาร์เรย์แบบดั้งเดิม

var test = {};
test[2300] = 'some string';
console.log(test);

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

อาร์เรย์ไม่สามารถเชื่อมโยง Graza ได้ หากคุณพยายามใช้คีย์ในอาร์เรย์แล้วทำซ้ำอีกครั้งคุณจะสังเกตเห็นว่าคุณกำลังทำซ้ำตามวิธีการและคุณสมบัติเริ่มต้นทั้งหมดของอาร์เรย์ -> ไม่เป็นที่ต้องการมากนัก
Swizec Teller

@Swizec - ทำไมฉันถึงพูดว่า "สับสนอย่างน่าขัน" คุณสามารถใช้อาร์เรย์เป็นอาร์เรย์ที่เชื่อมโยง - ซึ่งเป็นคู่ชื่อ / ค่า แต่คุณไม่ต้องการวนซ้ำอีก! (ฉันแค่ชี้ให้เห็นถึงเทคนิคไม่ใช่สิ่งที่ฉันอยากจะแนะนำให้ทำเลย)
Graza

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

3

ลองใช้ Object ไม่ใช่ Array:

var test = new Object(); test[2300] = 'Some string';

3
นี่เป็นวิธีที่จะไปแน่นอน ด้วยวิธีนี้คุณจะไม่สร้างอาร์เรย์ยาว 2300 รายการเพื่อจัดเก็บสตริงเดียว
Krystian

2
อาร์เรย์ JS ของ @Krystian เป็นอาร์เรย์ปลอม เรียกใช้var a = []; a[Math.pow(2, 30)] = 'hello';และคุณจะไม่เห็นการใช้งานเบราว์เซอร์ / หน่วยความจำเกินกว่ากิกะไบต์ แต่คุณจะเห็นa.lengthคือ 1073741824 VMs จัดเก็บ "อาร์เรย์" บางส่วนอย่างชัดเจนโดยใช้โครงสร้างข้อมูลอื่น ๆ ฉันเดาว่าเป็นเพียงแฮชแท็กอย่างน้อยก็ถ้า เบาบางพอสมควร
Andy

2

รับค่าสำหรับคุณสมบัติของอาร์เรย์ที่เชื่อมโยงเมื่อชื่อคุณสมบัติเป็นจำนวนเต็ม:

เริ่มต้นด้วยอาร์เรย์ที่เชื่อมโยงโดยที่ชื่อคุณสมบัติเป็นจำนวนเต็ม:

var categories = [
    {"1": "Category 1"},
    {"2": "Category 2"},
    {"3": "Category 3"},
    {"4": "Category 4"}
];

พุชรายการไปยังอาร์เรย์:

categories.push({"2300": "Category 2300"});
categories.push({"2301": "Category 2301"});

วนรอบอาร์เรย์และทำบางอย่างกับค่าคุณสมบัติ

for (var i = 0; i < categories.length; i++) {
    for (var categoryid in categories[i]) {
        var category = categories[i][categoryid];
        // Log progress to the console
        console.log(categoryid + ": " + category);
        //  ... do something
    }
}

เอาต์พุตคอนโซลควรมีลักษณะดังนี้:

1: Category 1
2: Category 2
3: Category 3
4: Category 4
2300: Category 2300
2301: Category 2301

อย่างที่คุณเห็นคุณสามารถหลีกเลี่ยงข้อ จำกัด อาร์เรย์ที่เชื่อมโยงได้และมีชื่อคุณสมบัติเป็นจำนวนเต็ม

หมายเหตุ: Associative array ในตัวอย่างของฉันคือเนื้อหา JSON ที่คุณจะมีหากคุณทำให้อ็อบเจ็กต์ Dictionary <string, string> [] เป็นอนุกรม


0

ใช้ออบเจ็กต์ - โดยมีจำนวนเต็มเป็นคีย์ - แทนที่จะใช้อาร์เรย์


0

บางครั้งฉันใช้คำนำหน้าสำหรับคีย์ของฉัน ตัวอย่างเช่น:

var pre = 'foo',
    key = pre + 1234

obj = {};

obj[key] = val;

ตอนนี้คุณไม่มีปัญหาในการเข้าถึง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.