如何在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]...].

如何在JavaScript中将对象转换为键值对数组?

Answers:


428

您可以使用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

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自2016年6月起,Chrome 54自同年10月,Edge 8月14日起。不完全是几分钟前。
凯尔

仅供参考:Object.entries将返回[key,value],但是键将是一个字符串,值将有所不同。
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在上面的示例中使用了箭头函数和map回调,以便可以利用Object.assign返回分配给对象的事实将其保留在一条指令中,而单个指令箭头函数的返回值就是该指令的结果。

这等效于:

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

如@TravisClarke在评论中提到的,map函数可以简化为:

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

但是,这将为每个键值对创建一个新数组,而不是就地修改现有数组,因此使创建的键值对数组的数量增加了一倍。虽然原始条目数组仍可访问,但不会对其进行垃圾回收。

现在,即使使用就地方法,仍然使用两个保存键值对的数组(输入和输出数组),但数组的总数仅改变了一个。输入和输出数组实际上并没有填充数组,而是对数组的引用,这些引用在内存中的空间可忽略不计。

  • 就地修改每个键值对导致的内存增长量可以忽略不计,但是需要再输入几个字符。
  • 为每个键值对创建一个新数组将使所需的内存量增加一倍,但需要减少输入几个字符。

您可以更进一步,通过就地修改entrys数组而不是将其映射到新数组来完全消除增长:

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]]);
特拉维斯·克拉克

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

  • 使用object属性作为新数组的键(可以创建稀疏数组):

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]

最后一种方法,它还可以根据键的值重新组织数组顺序。有时这可能是所需的行为(有时不是)。但是现在的好处是,这些值在正确的数组插槽上索引,这对于在数组插槽上进行搜索是必不可少的。

  • 映射而不是数组

最后(不是完整性问题,而是完整性问题),如果您需要使用键或值轻松搜索,但又不需要稀疏数组,不重复且无需重新排序而无需转换为数字键(甚至可以访问非常复杂的键),那么数组(或对象)就不是您所需要的。我将建议Map

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map

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

2
第四个要点及以后的内容与该问题完全无关,其余的答案只是在此处总结了前三个答案。这个答案不会给讨论带来任何尚未在这里或不是完全不相关的问题。

是的,作为第一行状态,这是答案的摘要,然后将其更新为使用现代ES6技术而非完整的打击功能。从支持关联数组的语言(例如PHP)中移动JSON数组时,第四个答案很有用。
卡洛斯·H。

这里提供的所有方法已经以最简单的形式在前三个答案中的两个中提供了,它们不在函数中,所以我不知道您在做什么。就我说的第四点而言,它与提出的问题完全无关。这可能与另一个问题有关,但与这个问题无关。无论如何,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循环的问题。这样就在保留结构的同时删除了索引。
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.keysArray#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格式的Object的每个元素,然后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.valuesArray#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 } ]

使用对象键在输出数组中

如果您改写(“ genre”是您选择的字符串):

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

我们可以将Key的Number更改为String类型,如下所示:

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)

0

简单的解决方案

`

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.