การสร้างคีย์แบบไดนามิกในอาร์เรย์ที่เชื่อมโยงกับ JavaScript


199

ฉันจะสร้างคีย์แบบไดนามิกในอาร์เรย์ที่เชื่อมโยงกับจาวาสคริปต์ได้อย่างไร

เอกสารทั้งหมดที่ฉันได้พบคือการอัปเดตคีย์ที่สร้างขึ้นแล้ว:

 arr['key'] = val;

ฉันมีสตริงเช่นนี้ " name = oscar "

และฉันต้องการที่จะจบลงด้วยสิ่งนี้:

{ name: 'whatever' }

นั่นคือฉันแบ่งสตริงและรับองค์ประกอบแรกและฉันต้องการวางไว้ในพจนานุกรม

รหัส

var text = ' name = oscar '
var dict = new Array();
var keyValuePair = text.split(' = ');
dict[ keyValuePair[0] ] = 'whatever';
alert( dict ); // prints nothing.

24
ข้ามลิงก์ไปยังคำตอบของ Eugeneเพื่อความสะดวก
user56reinstatemonica8

คำตอบ:


142

ใช้ตัวอย่างแรก หากไม่มีคีย์ก็จะถูกเพิ่ม

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

จะปรากฏขึ้นกล่องข้อความที่มี 'oscar'

ลอง:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );

ฉันวิ่งนั่นเป็นตัวอย่างใน Firefox เพื่อให้แน่ใจ คุณแน่ใจหรือไม่ที่จะใส่ 'ชื่อ' ในเครื่องหมายคำพูด?
tvanfosson

1
อืมมมมมเพราะฉันกำลังสร้างคีย์ "ไดนามิก" ไม่ใช่แบบคงที่ ผมขอ Doublecheck ล่ะค่ะ :)
OscarRyz

2
โปรดอ้างถึงคำอธิบายที่สมบูรณ์ยิ่งขึ้นของ Danny คุณจะไม่สามารถอ้างถึงค่าอาร์เรย์ใน for for loop ที่มีดัชนี (เช่น myarray [i]) หวังว่าจะไม่สับสนเกินไป
MK_Dev

4
ยิ่งไปกว่านั้นคือการใช้ Object (วงเล็บ {} สัญกรณ์) เพื่อหลีกเลี่ยงค่าใช้จ่ายในการมี. length, .slice () ฯลฯ ซึ่งรวมอยู่ใน Array prototype
bjornl

488

อย่างใดตัวอย่างทั้งหมดในขณะที่ทำงานได้ดีมี overcomplicated:

  • พวกเขาใช้new Array()ซึ่งเป็น overkill (และค่าใช้จ่าย) สำหรับอาร์เรย์เชื่อมโยงอย่างง่าย (พจนานุกรม AKA)
  • new Object()คนที่ดีกว่าใช้ ทำงานได้ดี แต่ทำไมการพิมพ์พิเศษทั้งหมดนี้?

คำถามนี้ถูกแท็ก "ผู้เริ่มต้น" ดังนั้นทำให้มันง่าย

วิธีง่าย ๆ ในการใช้พจนานุกรมใน JavaScript หรือ "ทำไม JavaScript ไม่มีวัตถุพจนานุกรมพิเศษ":

// create an empty associative array (in JavaScript it is called ... Object)
var dict = {};   // huh? {} is a shortcut for "new Object()"

// add a key named fred with value 42
dict.fred = 42;  // we can do that because "fred" is a constant
                 // and conforms to id rules

// add a key named 2bob2 with value "twins!"
dict["2bob2"] = "twins!";  // we use the subscript notation because
                           // the key is arbitrary (not id)

// add an arbitrary dynamic key with a dynamic value
var key = ..., // insanely complex calculations for the key
    val = ...; // insanely complex calculations for the value
dict[key] = val;

// read value of "fred"
val = dict.fred;

// read value of 2bob2
val = dict["2bob2"];

// read value of our cool secret key
val = dict[key];

ตอนนี้ขอเปลี่ยนค่า:

// change the value of fred
dict.fred = "astra";
// the assignment creates and/or replaces key-value pairs

// change value of 2bob2
dict["2bob2"] = [1, 2, 3];  // any legal value can be used

// change value of our secret key
dict[key] = undefined;
// contrary to popular beliefs assigning "undefined" does not remove the key

// go over all keys and values in our dictionary
for (key in dict) {
  // for-in loop goes over all properties including inherited properties
  // let's use only our own properties
  if (dict.hasOwnProperty(key)) {
    console.log("key = " + key + ", value = " + dict[key]);
  }
}

การลบค่าก็ทำได้ง่ายเช่นกัน:

// let's delete fred
delete dict.fred;
// fred is removed, the rest is still intact

// let's delete 2bob2
delete dict["2bob2"];

// let's delete our secret key
delete dict[key];

// now dict is empty

// let's replace it, recreating all original data
dict = {
  fred:    42,
  "2bob2": "twins!"
  // we can't add the original secret key because it was dynamic,
  // we can only add static keys
  // ...
  // oh well
  temp1:   val
};
// let's rename temp1 into our secret key:
if (key != "temp1") {
  dict[key] = dict.temp1; // copy the value
  delete dict.temp1;      // kill the old key
} else {
  // do nothing, we are good ;-)
}

2
สวัสดีฉันรู้ว่าฉันกำลังตอบกลับคำตอบเก่า แต่มันติดอันดับสูงใน Google ดังนั้นฉันจะถามต่อไป ฉันสับสนในสิ่งที่ "เราไม่สามารถเพิ่มคีย์ลับดั้งเดิมได้เนื่องจากมันเป็นแบบไดนามิกเราสามารถเพิ่มคีย์แบบคงที่" ในตัวอย่างของคุณ
Karel Bílek

1
มันหมายถึงสิ่งที่มันบอกอย่างแม่นยำ: เราไม่ทราบคุณค่าของมันดังนั้นเราจึงไม่สามารถแทนค่าเป็นค่าคงที่ซึ่งจำเป็นเมื่อระบุคีย์ในวัตถุตามตัวอักษร
Eugene Lazutkin

3
อย่างไรก็ตาม "เราไม่สามารถเพิ่มคีย์ลับดั้งเดิมได้เนื่องจากเป็นไดนามิก" ไม่ถูกต้องด้วยตัวเองแม้ว่าคุณจะไม่สามารถใช้ตัวแปรเป็นคีย์โดยตรงใน {} หรือเป็นคีย์ที่มีเครื่องหมายจุด เรายังสามารถเพิ่มคีย์ไดนามิกผ่าน "dict [key] = val" ตามที่คุณแสดงในตัวอย่างก่อนหน้านี้ ข้อ จำกัด เกิดจากการใช้ {} -notation แทนที่จะเป็นคีย์เอง
Zut

8
ดูเหมือนว่าคำตอบของ Sheldon Cooper's :)
jpatiaga

4
คำตอบที่สมบูรณ์แบบที่สมบูรณ์ควรเป็นค่าเริ่มต้น
Dennis Golomazov

29

จาวาสคริปต์ที่ไม่ได้มีการเชื่อมโยงอาร์เรย์ก็มีวัตถุ

บรรทัดของรหัสต่อไปนี้ทำในสิ่งเดียวกัน - ตั้งค่าฟิลด์ 'ชื่อ' บนวัตถุเป็น 'orion'

var f = new Object(); f.name = 'orion';
var f = new Object(); f['name'] = 'orion';
var f = new Array(); f.name = 'orion';
var f = new Array(); f['name'] = 'orion';
var f = new XMLHttpRequest(); f['name'] = 'orion';

ดูเหมือนว่าคุณมีอาเรย์แบบเชื่อมโยงเพราะแบบArrayนั้นเป็นแบบObject- อย่างไรก็ตามคุณไม่ได้เพิ่มสิ่งต่าง ๆ ลงในอาเรย์เลยคุณกำลังตั้งค่าฟิลด์บนวัตถุ

หลังจากที่ล้างข้อมูลแล้วนี่คือวิธีแก้ปัญหาสำหรับตัวอย่างของคุณ

var text = '{ name = oscar }'
var dict = new Object();

// Remove {} and spaces
var cleaned = text.replace(/[{} ]/g, '');

// split into key and value
var kvp = cleaned.split('=');

// put in the object
dict[ kvp[0] ] = kvp[1];
alert( dict.name ); // prints oscar.

สมมติว่าสตริงข้อความมีวงเล็บปีกกาจริง ๆ คุณสามารถทำอย่างนั้นมากขึ้นหรือน้อยลงในฐานะ JSON .. แทนที่เครื่องหมาย = ด้วย a: และคุณมีออบเจกต์เพื่อประเมิน ..
neonski

1
อ๊ะสตริงไม่ได้ถูกคั่นอย่างถูกต้อง regex ไม่สามารถแก้ไขได้
neonski

9

ในการตอบสนองต่อ MK_Dev คุณสามารถทำซ้ำได้ แต่ไม่ต่อเนื่องกัน (สำหรับการที่ชัดเจนจำเป็นต้องมีอาร์เรย์)

การค้นหา google อย่างรวดเร็วจะแสดงตารางแฮชใน javascript

โค้ดตัวอย่างสำหรับการวนลูปมากกว่าค่าในแฮช (จากลิงก์ข้างต้น):

var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

5

รหัสเดิม (ฉันเพิ่มหมายเลขบรรทัดเพื่ออ้างอิงได้):

1  var text = ' name = oscar '
2  var dict = new Array();
3  var keyValuePair = text.split(' = ');
4  dict[ keyValuePair[0] ] = 'whatever';
5  alert( dict ); // prints nothing.

เกือบจะมี...

  • บรรทัดที่ 1: คุณควรทำในข้อความเพื่อให้มันเป็นtrimname = oscar
  • บรรทัดที่ 3: โอเคตราบใดที่คุณมีช่องว่างโดยรอบเสมอ อาจดีกว่าถ้าไม่trimอยู่ในบรรทัด 1 ให้ใช้=และตัดแต่งแต่ละ keyValuePair
  • เพิ่มบรรทัดหลัง 3 และก่อน 4:

    key = keyValuePair[0];`
  • บรรทัด 4: ตอนนี้กลายเป็น:

    dict[key] = keyValuePair[1];
  • บรรทัด 5: เปลี่ยนเป็น:

    alert( dict['name'] );  // it will print out 'oscar'

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

หวังว่าจะช่วย


4

เบราว์เซอร์ที่ทันสมัยทั้งหมดรองรับแผนที่ซึ่งเป็นคีย์ข้อมูล / ค่าที่เข้มงวด มีสาเหตุสองประการที่ทำให้การใช้แผนที่ดีกว่าวัตถุ:

  • วัตถุมีต้นแบบดังนั้นจึงมีปุ่มเริ่มต้นในแผนที่
  • กุญแจของวัตถุคือ Strings ซึ่งสามารถเป็นค่าใด ๆ สำหรับแผนที่
  • คุณสามารถรับขนาดของแผนที่ได้อย่างง่ายดายในขณะที่คุณต้องติดตามขนาดของวัตถุ

ตัวอย่าง:

var myMap = new Map();

var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";

myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

หากคุณต้องการให้คีย์ที่ไม่ได้อ้างอิงจากวัตถุอื่นเพื่อรวบรวมขยะให้ลองใช้WeakMapแทนการใช้แผนที่



1
var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

สิ่งนี้ใช้ได้ แต่ทำซ้ำผ่านคุณสมบัติทุกอย่างของวัตถุอาร์เรย์ ถ้าคุณต้องการวนซ้ำคุณสมบัติ myArray.one, myArray.two ... คุณลองแบบนี้

myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
myArray.push("one");
myArray.push("two");
myArray.push("three");
for(i=0;i<maArray.length;i++{
    console.log(myArray[myArray[i]])
}

ตอนนี้คุณสามารถเข้าถึงทั้งสองโดย myArray ["หนึ่ง"] และวนซ้ำผ่านคุณสมบัติเหล่านี้เท่านั้น


คุณนับจำนวนมิสเซิลในตัวอย่างของคุณหรือไม่? :-) maArray ถูกลืมปิด ')' ...
Brian Haak

ขอบคุณสำหรับตัวอย่าง เราสามารถรวมตัวกันArrayและObjectและทำงานเฉพาะกับObjectต้นไม้! ความเข้าใจที่ยอดเยี่ยม! มันมีประโยชน์มากที่จะทำObject.getOwnPropertyNames(obj/array)!
Brian Haak

1
var obj = {};

                for (i = 0; i < data.length; i++) {
                    if(i%2==0) {
                        var left = data[i].substring(data[i].indexOf('.') + 1);
                        var right = data[i + 1].substring(data[i + 1].indexOf('.') + 1);

                        obj[left] = right;
                        count++;
                    }
                }
                console.log("obj");
                console.log(obj);
                // show the values stored
                for (var i in obj) {
                    console.log('key is: ' + i + ', value is: ' + obj[i]);
                }

            }
        };

}

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