Cách chuyển đổi Đối tượng {} thành Mảng [] của các cặp khóa-giá trị trong JavaScript


243

Tôi muốn chuyển đổi một đối tượng như thế này:

{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

vào một mảng các cặp khóa-giá trị như thế này:

[[1,5],[2,7],[3,0],[4,0]...].

Làm cách nào tôi có thể chuyển đổi Đối tượng thành Mảng các cặp khóa-giá trị trong JavaScript?

Câu trả lời:


428

Bạn có thể sử dụng Object.keys()map()để làm điều này

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [Number(key), obj[key]];
});

console.log(result);


6
@blvckasvp Bạn có đang sử dụng số làm chìa khóa của mình không? Nếu không, khi nó cố gắng chuyển đổi khóa của bạn thành một số, nó sẽ thất bại và NaNthay vào đó. Nếu bạn muốn sử dụng chuỗi như là chìa khóa của bạn, thay đổi trở về từ [Number(key), obj[key]]đến [key, obj[key]]hoặc sử dụng Object.entriesnhư @Pila gợi ý trong câu trả lời của họ
scottbot95

123

Cách tốt nhất là làm:

var obj ={"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10"‌​:0,"11":0,"12":0} 
Object.entries(obj);

Gọi entries, như được hiển thị ở đây, sẽ trở lại[key, value] các cặp, như người hỏi yêu cầu.

Ngoài ra, bạn có thể gọi Object.values(obj), sẽ chỉ trả về các giá trị.


6
Kính gửi các nhà phát triển, vui lòng kiểm tra bảng tương thích ECMA trước khi áp dụng các chức năng tốt đẹp này chỉ tương thích với các trình duyệt được phát hành vài phút trước.
andreszs

8
@andreszs Xem Tôi có thể sử dụng bảng không, nếu bạn không ngại bỏ hỗ trợ IE (và vào năm 2019, tôi hy vọng sự tỉnh táo của bạn rằng bạn thực sự không) thì bạn sẽ khá tốt để đi. FF 47 là từ tháng 6 năm 2016 và Chrome 54 là từ tháng 10 cùng năm, Edge 14 tháng 8. Không chính xác vài phút trước.
Kyll

FYI: Object.entries sẽ trả về [key, value], nhưng khóa sẽ là một chuỗi, giá trị sẽ khác nhau.
SHAHBAZ

61

Object.entries()trả về một mảng có các phần tử là các mảng tương ứng với các [key, value]cặp thuộc tính có thể đếm được tìm thấy trực tiếp object. Thứ tự của các thuộc tính giống như thứ tự được đưa ra bằng cách lặp qua các giá trị thuộc tính của đối tượng theo cách thủ công.

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Descrip

Các Object.entrieschức năng lợi nhuận gần như đầu ra chính xác mà bạn đang yêu cầu, trừ các phím là chuỗi thay vì con số.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

console.log(Object.entries(obj));

Nếu bạn cần các khóa là số, bạn có thể ánh xạ kết quả sang một mảng mới với chức năng gọi lại thay thế khóa trong mỗi cặp bằng một số được ép từ nó.

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
    const entries = Object.entries(input);
    return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}

console.log(toNumericPairs(obj));

Tôi sử dụng một hàm mũi tên và Object.assigncho hàm gọi lại bản đồ trong ví dụ trên để tôi có thể giữ nó trong một lệnh bằng cách tận dụng thực tế Object.assigntrả về đối tượng được gán và giá trị trả về của một mũi tên lệnh là kết quả của lệnh.

Điều này tương đương với:

entry => {
    entry[0] = +entry[0];
    return entry;
}

Như @TravisClarke đã đề cập trong các bình luận, chức năng bản đồ có thể được rút ngắn thành:

entry => [ +entry[0], entry[1] ]

Tuy nhiên, điều đó sẽ tạo ra một mảng mới cho mỗi cặp khóa-giá trị, thay vì sửa đổi mảng hiện có tại chỗ, do đó nhân đôi số lượng mảng cặp giá trị khóa được tạo. Mặc dù mảng mục nhập ban đầu vẫn có thể truy cập, nhưng các mục nhập của nó sẽ không được thu gom rác.

Bây giờ, mặc dù sử dụng phương thức tại chỗ của chúng tôi vẫn sử dụng hai mảng chứa các cặp giá trị khóa (mảng đầu vào và mảng đầu ra), tổng số mảng chỉ thay đổi theo một. Các mảng đầu vào và đầu ra không thực sự chứa đầy các mảng, mà là các tham chiếu đến các mảng và các tham chiếu đó chiếm một lượng không gian không đáng kể trong bộ nhớ.

  • Sửa đổi từng cặp khóa-giá trị tại chỗ dẫn đến tăng trưởng bộ nhớ không đáng kể, nhưng yêu cầu nhập thêm một vài ký tự.
  • Tạo một mảng mới cho mỗi cặp khóa-giá trị dẫn đến nhân đôi số lượng bộ nhớ cần thiết, nhưng yêu cầu nhập ít hơn một vài ký tự.

Bạn có thể tiến thêm một bước và loại bỏ hoàn toàn sự tăng trưởng bằng cách sửa đổi mảng mục nhập tại chỗ thay vì ánh xạ nó sang một mảng mới:

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
  const entries = Object.entries(obj);
  entries.forEach(entry => entry[0] = +entry[0]);
  return entries;
}

console.log(toNumericPairs(obj));


1
Tôi thích cách tiếp cận chức năng. Thay thế ngắn hơn:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke

20

Để tóm tắt một số câu trả lời ngay bây giờ vào năm 2018, trong đó ES6 là tiêu chuẩn.

Bắt đầu với đối tượng:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • Chỉ cần mù quáng nhận các giá trị trên một mảng, không quan tâm đến các phím:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]

  • Đơn giản nhận các cặp trên một mảng:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]

  • Tương tự như trước, nhưng với các phím số trên mỗi cặp:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]

  • Sử dụng thuộc tính đối tượng làm khóa cho một mảng mới (có thể tạo các mảng thưa thớt):

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]

Phương pháp cuối cùng này, nó cũng có thể sắp xếp lại thứ tự mảng tùy thuộc vào giá trị của các khóa. Đôi khi, đây có thể là hành vi mong muốn (đôi khi không). Nhưng lợi thế bây giờ là các giá trị được lập chỉ mục trên vị trí mảng chính xác, cần thiết và tầm thường để thực hiện tìm kiếm trên đó.

  • Bản đồ thay vì Mảng

Cuối cùng (không phải là một phần của câu hỏi ban đầu, nhưng để hoàn thiện), nếu bạn cần dễ dàng tìm kiếm bằng cách sử dụng khóa hoặc giá trị, nhưng bạn không muốn các mảng thưa thớt, không trùng lặp và không sắp xếp lại mà không cần phải chuyển đổi thành các phím số ( thậm chí có thể truy cập các khóa rất phức tạp), sau đó mảng (hoặc đối tượng) không phải là thứ bạn cần. Tôi sẽ đề nghị Mapthay thế:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true

2
Điểm đạn thứ tư trở đi hoàn toàn không liên quan đến câu hỏi và phần còn lại của câu trả lời của bạn chỉ là tóm tắt ba câu trả lời hàng đầu ở đây. Câu trả lời này không mang lại bất cứ điều gì cho cuộc thảo luận chưa có ở đây hoặc không hoàn toàn không liên quan.

Có, là trạng thái dòng đầu tiên, đây là bản tóm tắt các câu trả lời, sau đó cập nhật chúng để sử dụng các kỹ thuật ES6 hiện đại thay vì các chức năng thổi hoàn toàn. Câu trả lời thứ tư rất hữu ích khi bạn di chuyển các mảng JSON từ một ngôn ngữ hỗ trợ các mảng kết hợp (ví dụ: PHP).
CarlosH.

Tất cả các phương thức được cung cấp ở đây đã được cung cấp ở dạng đơn giản trong hai trong ba câu trả lời hàng đầu, chúng không có chức năng nên tôi không biết bạn đang làm gì ở đó. Theo như thứ 4, như tôi đã nói, nó hoàn toàn không liên quan đến câu hỏi được hỏi. Nó có thể liên quan đến một câu hỏi khác, nhưng không phải câu hỏi này. Bất kể, JSON là JSON cho dù nó được tạo bằng PHP, JavaScript hoặc Haskell.

18

Một giải pháp khác nếu Object.entrieskhông làm việc cho bạn.

const obj = {
      '1': 29,
      '2': 42
    };
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);


1
Điều này làm việc cho tôi. Tôi gặp phải một vấn đề trong đó việc nhập các chỉ mục đã thêm JSON khiến cho không thể sử dụng vòng lặp AngFor ngFor. Điều này loại bỏ các chỉ mục trong khi bảo tồn cấu trúc.
RAC

@RAC +1 để sử dụng "chỉ mục" thay vì "chỉ mục". Bắt đầu, cổ xưa (tức là tùy tiện và vô nghĩa lệch lạc) truyền thống tiếng Anh!
Venryx

12

Trong Ecmascript 6,

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

var res = Object.entries(obj);

console.log(res);

vĩ cầm


Không chắc chắn lý do tại sao điều này đã bị hạ cấp, hoạt động hoàn toàn tốt
sMstyle 28/12/18

1
Tôi đã không downvote, nhưng lưu ý rằng .map((value)=>(value))phần này là vô nghĩa - nó chỉ trả về một mảng mục nhập chính xác tương đương với phần thu được từ Object.entries(obj)cuộc gọi.
Venryx

8

Sử dụng Object.keysArray#mapphương pháp.

var obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};
// get all object property names
var res = Object.keys(obj)
  // iterate over them and generate the array
  .map(function(k) {
    // generate the array element 
    return [+k, obj[k]];
  });

console.log(res);


7

Sử dụng Object.entriesđể có được từng phần tử của Object ở key & valueđịnh dạng, sau đó mapthông qua chúng như thế này:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));

console.log(res);

Nhưng, nếu bạn chắc chắn rằng các phím sẽ theo thứ tự lũy tiến, bạn có thể sử dụng Object.valuesArray#maplàm một cái gì đó như thế này:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}; 

                        // idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));

console.log(result);


5

Nếu bạn đang sử dụng lodash, nó có thể đơn giản như thế này:

var arr = _.values(obj);

5

Với lodash, ngoài câu trả lời được cung cấp ở trên, bạn cũng có thể có khóa trong mảng đầu ra.

Không có các khóa đối tượng trong mảng đầu ra

cho:

const array = _.values(obj);

Nếu obj là như sau:

{ art”: { id: 1,  title: aaaa }, fiction”: { id: 22,  title: 7777”} }

Sau đó, mảng sẽ là:

[ { id: 1, title: aaaa }, { id: 22, title: 7777 } ]

Với các khóa đối tượng trong mảng đầu ra

Nếu bạn viết thay thế ('thể loại' là một chuỗi mà bạn chọn):

const array= _.map(obj, (val, id) => {
    return { ...val, genre: key };
  });

Bạn sẽ nhận được:

[ 
  { id: 1, title: aaaa , genre: art”}, 
  { id: 22, title: 7777”, genre: fiction }
]

4

Tôi muốn đề xuất giải pháp đơn giản nhất này để sử dụng Object.entries()

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result =Object.entries(obj)

console.log(result);


1

Bạn có thể sử dụng Object.values([]), bạn có thể cần polyfill này nếu bạn chưa:

const objectToValuesPolyfill = (object) => {
  return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;

https://stackoverflow.com/a/54822153/846348

Sau đó, bạn có thể làm:

var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);

Chỉ cần nhớ rằng các mảng trong js chỉ có thể sử dụng các khóa số, vì vậy nếu bạn đã sử dụng một cái gì đó khác trong đối tượng thì chúng sẽ trở thành `0,1,2 ... x``

Nó có thể hữu ích để loại bỏ các bản sao chẳng hạn nếu bạn có một khóa duy nhất.

var obj = {};
object[uniqueKey] = '...';

0

Sử dụng cho

var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
            "8":0, "9":0, "10":0, "11":0, "12":0 };

var objectToArray = function(obj) {
    var _arr = [];

    for (var key in obj) {
        _arr.push([key, obj[key]]);
    }
    return _arr;
}

console.log(objectToArray(obj));

0

Chuyển đổi đệ quy đối tượng thành mảng

function is_object(mixed_var) {
    if (mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}


function objectToArray(obj) {
    var array = [], tempObject;
    for (var key in obj) {

        tempObject = obj[key];

        if (is_object(obj[key])) {
            tempObject = objectToArray(obj[key]);
        }
        array[key] = tempObject;
    }
    return array;
}

0

Chúng ta có thể thay đổi loại Number thành String cho Key như bên dưới:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [String(key), obj[key]];
});
    
console.log(result);


0

Đây là giải pháp của tôi, tôi có cùng một vấn đề và có vẻ như giải pháp này hiệu quả với tôi.

yourObj = [].concat(yourObj);

0

Đây là cách thực hiện barebone đơn giản của tôi:

let obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};    

const objectToArray = obj => {
      let sol = [];
      for (key in obj) {
        sol.push([key, obj[key]]);
      }
      return sol;
    };

objectToArray(obj)

0

Giải pháp đơn giản

`

var result = Object.keys(records).map(function (value) {
         return { [value]: records[value] };
});
console.log(result);


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.