วิธีการแปลง Object {} เป็น Array [] ของคู่ของคีย์ - ค่าใน JavaScript


243

ฉันต้องการแปลงวัตถุเช่นนี้:

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

ลงในอาร์เรย์ของคู่ของคีย์ - ค่าเช่นนี้

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

ฉันจะแปลง Object เป็น Array ของคู่คีย์ - ค่าใน JavaScript ได้อย่างไร

คำตอบ:


429

คุณสามารถใช้Object.keys()และmap()เพื่อทำสิ่งนี้

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 คุณใช้หมายเลขเป็นกุญแจของคุณหรือไม่ ถ้าไม่เมื่อมันพยายามแปลงคีย์ของคุณเป็นตัวเลขมันจะล้มเหลวและกลับมาNaNแทน หากคุณต้องการใช้สตริงเป็นกุญแจของคุณให้เปลี่ยนผลตอบแทนจาก[Number(key), obj[key]]เป็น[key, obj[key]]หรือใช้Object.entriesเป็น @Pila ที่แนะนำในคำตอบของพวกเขา
scottbot95

123

วิธีที่ดีที่สุดคือทำ:

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

การเรียกร้อง entriesดังที่แสดงไว้ที่นี่จะคืนค่า[key, value]คู่ตามที่ผู้ถามร้องขอ

หรือคุณสามารถโทรหาObject.values(obj)ซึ่งจะคืนค่าเฉพาะ


6
ผู้พัฒนาที่รักโปรดตรวจสอบตารางความเข้ากันได้ ECMA ก่อนที่จะใช้ฟังก์ชั่นที่ดีเหล่านี้ที่เข้ากันได้กับเบราว์เซอร์ที่วางจำหน่ายเมื่อไม่กี่นาทีที่ผ่านมา
andreszs

8
@andreszs ดูฉันใช้โต๊ะถ้าคุณไม่รังเกียจที่จะทิ้งการสนับสนุน IE (และในปี 2019 ฉันหวังว่าสติของคุณที่คุณทำไม่ได้จริงๆ) จากนั้นคุณก็ค่อนข้างดีที่จะไป FF 47 มาจากมิถุนายน 2559 และ Chrome 54 มาจากตุลาคมของปีเดียวกัน Edge 14 สิงหาคม ไม่กี่นาทีก่อน
Kyll

FYI: Object.entries จะส่งกลับ [คีย์ค่า] แต่คีย์จะเป็นสตริงค่าจะแตกต่างกัน
SHAHBAZ

62

Object.entries()ส่งกลับอาร์เรย์ซึ่งเป็นธาตุอาร์เรย์ที่สอดคล้องกับคุณสมบัตินับคู่พบได้โดยตรงเมื่อ[key, value] objectการเรียงลำดับของคุณสมบัติเหมือนกับที่กำหนดโดยการวนลูปมากกว่าค่าคุณสมบัติของวัตถุด้วยตนเอง

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

Object.entriesกลับมาทำงานเกือบผลผลิตที่แน่นอนที่คุณขอยกเว้นคีย์มีสายแทนตัวเลข

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

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

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

ฉันใช้ฟังก์ชั่นลูกศรและObject.assignสำหรับการเรียกกลับแผนที่ในตัวอย่างด้านบนเพื่อให้ฉันสามารถเก็บไว้ในคำสั่งเดียวโดยใช้ประโยชน์จากความจริงที่Object.assignส่งคืนวัตถุที่ได้รับมอบหมายและค่าส่งคืนฟังก์ชั่นลูกศรคำสั่งเดียว

นี่เทียบเท่ากับ:

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

ตามที่กล่าวถึงโดย @TravisClarke ในความคิดเห็นฟังก์ชั่นแผนที่สามารถย่อให้เป็น:

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

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

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

  • การแก้ไขคู่คีย์ - ค่าแต่ละตำแหน่งจะส่งผลให้หน่วยความจำเพิ่มขึ้นเล็กน้อย แต่ต้องพิมพ์อักขระเพิ่มอีกสองสามตัว
  • การสร้างอาร์เรย์ใหม่สำหรับคู่คีย์ - ค่าแต่ละคู่จะส่งผลให้จำนวนหน่วยความจำที่ต้องการเพิ่มขึ้นเป็นสองเท่า แต่ต้องพิมพ์อักขระที่น้อยลง

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

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
ฉันชอบวิธีการทำงาน เป็นทางเลือกที่สั้นกว่า:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke

21

หากต้องการสรุปคำตอบเหล่านี้ในตอนนี้ในปี 2018 โดยที่ ES6 คือมาตรฐาน

เริ่มต้นด้วยวัตถุ:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • เพียงแค่รับค่าบนอาเรย์อย่างสุ่มสี่สุ่มห้าอย่าสนใจกุญแจ:

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]

  • ง่าย ๆ รับคู่ในอาร์เรย์:

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

  • เหมือนกับก่อนหน้า แต่มีปุ่มตัวเลขในแต่ละคู่:

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

  • การใช้คุณสมบัติวัตถุเป็นกุญแจสำคัญสำหรับอาร์เรย์ใหม่ (สามารถสร้างอาร์เรย์กระจัดกระจาย):

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]

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

  • แผนที่แทน Array

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

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
สัญลักษณ์แสดงหัวข้อย่อยที่สี่และต่อไปจะไม่เกี่ยวข้องกับคำถามอย่างสมบูรณ์และส่วนที่เหลือของคำตอบของคุณเป็นเพียงการสรุปคำตอบสามอันดับแรกที่นี่ คำตอบนี้ไม่ได้นำอะไรมาสู่การอภิปรายที่ไม่ได้อยู่ที่นี่หรือไม่เกี่ยวข้องอย่างสมบูรณ์

ใช่เป็นสถานะของบรรทัดแรกนี่เป็นบทสรุปของคำตอบจากนั้นอัปเดตพวกเขาเพื่อใช้เทคนิค ES6 ที่ทันสมัยแทนฟังก์ชั่นการระเบิดเต็ม คำตอบที่สี่มีประโยชน์เมื่อคุณกำลังย้ายอาร์เรย์ JSON จากภาษาที่สนับสนุนอาร์เรย์เชื่อมโยง (เช่น PHP)
CarlosH

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

18

วิธีแก้ปัญหาอื่นหากObject.entriesไม่ได้ผลสำหรับคุณ

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


1
สิ่งนี้ใช้ได้สำหรับฉัน ฉันประสบปัญหาที่การนำเข้า JSON เพิ่มดัชนีซึ่งทำให้ไม่สามารถใช้ Angulars ngFor loop ได้ สิ่งนี้จะลบดัชนีในขณะที่ยังคงโครงสร้างไว้
RAC

@RAC +1 สำหรับการใช้ "ดัชนี" แทน "ดัชนี" Begone, คร่ำครึ (เช่น. ประเพณีภาษาอังกฤษโดยพลการและไม่มีความหมาย)
Venryx

12

ใน 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);

ซอ


ไม่แน่ใจว่าทำไมการ
อัปเดต

1
ฉันไม่ได้ลงคะแนน แต่ทราบว่า.map((value)=>(value))ส่วนนั้นไม่มีความหมาย - เพียงส่งคืนอาร์เรย์ที่มีค่าเท่ากับจำนวนที่ได้รับจากการObject.entries(obj)โทร
Venryx

8

การใช้งานObject.keysและArray#mapวิธีการ

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

ใช้Object.entriesเพื่อให้ได้องค์ประกอบของวัตถุในkey & valueรูปแบบจากนั้นmapผ่านสิ่งเหล่านี้:

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

แต่ถ้าคุณมั่นใจว่ากุญแจจะอยู่ในลำดับขั้นสูงคุณสามารถใช้Object.valuesและArray#mapทำสิ่งนี้:

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

ด้วย lodash นอกเหนือจากคำตอบที่ให้ไว้ข้างต้นคุณสามารถมีคีย์ในอาร์เรย์เอาต์พุตได้

ไม่มีคีย์วัตถุในอาร์เรย์ผลลัพธ์

สำหรับ:

const array = _.values(obj);

หาก obj มีดังต่อไปนี้:

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

จากนั้นอาร์เรย์จะเป็น:

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

ด้วยปุ่มวัตถุในอาร์เรย์เอาท์พุท

หากคุณเขียนแทน ('ประเภท' เป็นสตริงที่คุณเลือก):

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

คุณจะได้รับ:

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

4

ฉันอยากจะแนะนำวิธีแก้ปัญหาที่ง่ายที่สุดในการใช้ 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

คุณสามารถใช้Object.values([])คุณอาจต้องใช้ polyfill นี้หากยังไม่ได้ทำ:

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

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

จากนั้นคุณสามารถทำได้:

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

เพียงจำไว้ว่าอาร์เรย์ใน js สามารถใช้คีย์ตัวเลขได้เท่านั้นดังนั้นหากคุณใช้อย่างอื่นในวัตถุดังนั้นสิ่งเหล่านั้นจะกลายเป็น '0,1,2 ... x`'

มันจะมีประโยชน์ในการลบรายการที่ซ้ำกันเช่นถ้าคุณมีคีย์ที่ไม่ซ้ำกัน

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

0

ใช้สำหรับใน

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

วนซ้ำแปลงวัตถุเป็นอาร์เรย์

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

เราสามารถเปลี่ยน Number เป็น String สำหรับ Key ดังด้านล่าง:

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

นี่คือวิธีการแก้ปัญหาของฉันฉันมีปัญหาเดียวกันและดูเหมือนว่าวิธีนี้ใช้ได้สำหรับฉัน

yourObj = [].concat(yourObj);

0

นี่คือการใช้แบร์โบนอย่างง่ายของฉัน:

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)


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