Tự động tạo các khóa trong mảng kết hợp JavaScript


199

Làm cách nào tôi có thể tự động tạo các khóa trong mảng kết hợp javascript?

Tất cả tài liệu tôi tìm thấy cho đến nay là cập nhật các khóa đã được tạo:

 arr['key'] = val;

Tôi có một chuỗi như thế này " name = oscar "

Và tôi muốn kết thúc với một cái gì đó như thế này:

{ name: 'whatever' }

Đó là tôi tách chuỗi và lấy phần tử đầu tiên, và tôi muốn đưa nó vào từ điển.

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

24
Chuyển liên kết đến câu trả lời của Eugene để thuận tiện
user56reinstatemonica8

Câu trả lời:


142

Sử dụng ví dụ đầu tiên. Nếu khóa không tồn tại, nó sẽ được thêm vào.

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

Sẽ bật lên một hộp thông báo có chứa 'oscar'.

Thử:

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

Tôi đã chạy nó như một mẫu trong Firefox để chắc chắn. Bạn có chắc chắn đặt 'tên' trong dấu ngoặc kép?
tvanfosson

1
Không, bởi vì, tôi đang tạo khóa "động" không tĩnh. Hãy để tôi nhân đôi bằng mọi cách :)
OscarRyz

2
Vui lòng tham khảo lời giải thích đầy đủ hơn của Danny. Bạn sẽ không thể tham chiếu các giá trị mảng trong một vòng lặp for với một chỉ mục (chẳng hạn như myarray [i]). Hy vọng điều đó không quá khó hiểu.
MK_Dev

4
Thậm chí tốt hơn là sử dụng một Đối tượng (ký hiệu {} ký hiệu) để tránh chi phí có .length, .slice (), v.v. được bao gồm trong nguyên mẫu Array
bjornl

488

Bằng cách nào đó, tất cả các ví dụ, trong khi hoạt động tốt, bị quá tải:

  • Họ sử dụng new Array(), đó là một mức quá mức (và chi phí chung) cho một mảng kết hợp đơn giản (từ điển AKA).
  • Những người tốt hơn sử dụng new Object(). Hoạt động tốt, nhưng tại sao tất cả các gõ thêm này?

Câu hỏi này được gắn thẻ "người mới bắt đầu", vì vậy hãy làm cho nó đơn giản.

Cách đơn giản để sử dụng từ điển trong JavaScript hoặc "Tại sao JavaScript không có đối tượng từ điển đặc biệt?":

// 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];

Bây giờ hãy thay đổi giá trị:

// 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]);
  }
}

Xóa các giá trị cũng dễ dàng:

// 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
Xin chào, tôi biết tôi đang trả lời câu trả lời cũ, nhưng nó được xếp hạng cao trên Google, vì vậy tôi sẽ hỏi bằng mọi cách. Tôi hơi bối rối về việc "chúng ta không thể thêm khóa bí mật ban đầu vì nó là động, chúng ta chỉ có thể thêm khóa tĩnh" nghĩa là trong ví dụ của bạn.
Karel Bílek

1
Nó có nghĩa chính xác những gì nó nói: chúng ta không biết giá trị của nó, vì vậy chúng ta không thể biểu diễn nó như một hằng số, điều này là bắt buộc khi chỉ định một khóa trong một đối tượng theo nghĩa đen.
Eugene Lazutkin

3
Tuy nhiên, "chúng tôi không thể thêm khóa bí mật ban đầu vì nó là động" không đúng, mặc dù bạn không thể sử dụng biến làm khóa trực tiếp trong {} hoặc làm khóa có ký hiệu dấu chấm. Chúng tôi vẫn có thể thêm khóa động thông qua "dict [key] = val", như bạn hiển thị sớm trong ví dụ. Giới hạn là với việc sử dụng chú thích {}, thay vì chính nó.
Zut

8
Điều này giống như câu trả lời của Sheldon Cooper :)
jpatiaga

4
câu trả lời hoàn chỉnh hoàn hảo, nên là mặc định
Dennis Golomazov

29

Javascript không có mảng kết hợp , nó có các đối tượng .

Tất cả các dòng mã sau đây thực hiện chính xác cùng một điều - đặt trường 'tên' trên một đối tượng thành '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';

Có vẻ như bạn có một mảng kết hợp bởi vì một Arraycũng là một Object- tuy nhiên bạn thực sự không thêm mọi thứ vào mảng đó, bạn đang đặt các trường trên đối tượng.

Bây giờ đã được xóa, đây là một giải pháp làm việc cho ví dụ của bạn

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.

Giả sử chuỗi văn bản thực sự có dấu ngoặc nhọn, bạn ít nhiều có thể coi nó là JSON .. thay thế dấu = bằng a: và bạn đã có một đối tượng để eval ..
neonski

1
Ooops, chuỗi không được phân định đúng. Không có gì regex không thể sửa chữa.
neonski

9

Đáp lại MK_Dev, người ta có thể lặp lại, nhưng không liên tiếp. (Đối với điều đó rõ ràng là một mảng là cần thiết)

Tìm kiếm nhanh trên google sẽ hiển thị các bảng băm trong javascript

Mã ví dụ để lặp qua các giá trị trong hàm băm (từ liên kết đã nói ở trên):

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

Mã gốc (Tôi đã thêm số dòng để có thể tham khảo chúng):

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.

Gần đến rồi ...

  • dòng 1: bạn nên làm một trimvăn bản như vậy name = oscar.
  • dòng 3: được miễn là bạn LUÔN LUÔN có khoảng trống xung quanh bạn. có thể tốt hơn để không trimở dòng 1, sử dụng =và cắt từng keyValuePair
  • thêm một dòng sau 3 và trước 4:

    key = keyValuePair[0];`
  • dòng 4: Bây giờ trở thành:

    dict[key] = keyValuePair[1];
  • dòng 5: Thay đổi thành:

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

Điều tôi đang cố gắng nói là dict[keyValuePair[0]]nó không hoạt động, bạn cần đặt một chuỗi keyValuePair[0]và sử dụng nó làm khóa kết hợp. Đó là cách duy nhất tôi có được của tôi để làm việc. Sau khi bạn đã thiết lập xong, bạn có thể tham chiếu nó với chỉ mục số hoặc khóa trong dấu ngoặc kép.

Mong rằng sẽ giúp.


4

Tất cả các trình duyệt hiện đại đều hỗ trợ Bản đồ , đây là một hạn chế dữ liệu chính / giá trị. Có một số lý do khiến việc sử dụng Bản đồ tốt hơn Đối tượng:

  • Một đối tượng có một nguyên mẫu, vì vậy có các khóa mặc định trong bản đồ.
  • Các khóa của Đối tượng là Chuỗi, trong đó chúng có thể là bất kỳ giá trị nào cho Bản đồ.
  • Bạn có thể dễ dàng lấy kích thước của Bản đồ trong khi bạn phải theo dõi kích thước cho Đối tượng.

Thí dụ:

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"

Nếu bạn muốn các khóa không được tham chiếu từ các đối tượng khác là rác được thu thập, hãy xem xét sử dụng WeakMap thay vì Bản đồ.



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]);
}

Điều này là ok nhưng lặp đi lặp lại qua mọi thuộc tính của đối tượng mảng. nếu bạn chỉ muốn lặp qua các thuộc tính myArray.one, myArray.two ... bạn hãy thử như thế này

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]])
}

bây giờ bạn có thể truy cập cả bằng myArray ["one"] và chỉ lặp qua các thuộc tính này.


Bạn đã đếm số lượng sương mù trong ví dụ của bạn chưa? :-) maArray, đã quên đóng ')' ...
Brian Haak

Cảm ơn ví dụ. Chúng tôi có thể đoàn kết ArrayObjectchỉ làm việc với Objectcây! Cái nhìn sâu sắc tuyệt vời! Nó rất hữu ích để thực hiện 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]);
                }

            }
        };

}

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.