将每个键具有多个值的对象转换为JS中的对象数组

时间:2018-08-13 13:55:38

标签: javascript json

我有一个看起来像这样的对象:

 obj={"a": [1,2],"b": [3,4],"c": [5,6]}

我需要创建一个对象数组,其中每个对象都由每个键组成,每个键只有一个对应于其顺序的值,如下所示:

obj2=[{"a": 1, "b": 3, "c": 5},{"a": 2, "b": 4, "c": 6}]

如果我使用JSON.stringify(obj)有一个JSON字符串,是否有可能直接从第一个字符串创建与JSON.stringify(obj2)相对应的字符串?

6 个答案:

答案 0 :(得分:1)

您可以使用Object.keysObject.values来提取键和值。使用Math.max获取值的最大长度。使用for循环并使用reduce制作新对象。

var obj = {"a": [1, 2],"b": [3, 4],"c": [5, 6]};

var keys = Object.keys(obj);
var values = Object.values(obj);

var obj2 = [];

for (i = 0; i < Math.max(...values.map(o => o.length)); i++) {
  obj2.push(keys.reduce((c, v, k) => Object.assign(c, {[v]: values[k][i] || ""}), {}))
}

console.log(obj2);

即使给定对象值的长度不同,这也将起作用。

var obj = {
  "a": [1, 2],
  "b": [3, 4],
  "c": [5, 6, 10]
};

var keys = Object.keys(obj);
var values = Object.values(obj);

var obj2 = [];

for (i = 0; i < Math.max(...values.map(o => o.length)); i++) {
  obj2.push(keys.reduce((c, v, k) => Object.assign(c, {[v]: values[k][i] || ""}), {}))
}

console.log(obj2);

答案 1 :(得分:0)

我相信这应该可以解决问题:

obj={"a": [1,2],"b": [3,4],"c": [5,6]}
 
const transform = input => Object.values(input)[0]
  .map((_, i) => Object.keys(input)
    .reduce((prev, curr) => {
      prev[curr] = input[curr][i]
      return prev
    }, {}))
    
const result = transform(obj)

console.dir(result)

这仅适用于每个值都是相同长度数组的对象。您获取第一个值的每个索引,然后为每个键创建一个对象,并使用上述索引获取该值。

答案 2 :(得分:0)

const obj = { "a": [1, 2], "b": [3, 4], "c": [5, 6] }
// create an array to store result
const result = []
// for each key in obj
Object.keys(obj).forEach(key => {
    // for each array element of the property obj[key]
    obj[key].forEach((value, index) => {
        // if an object doesn't exists at the current index in result
        // create it
        if (!result[index]) {
            result[index] = {}
        }
        // at the result index, set the key to the current value
        result[index][key] = value
    })
})
console.log(result)

给定预期结果,这是我的算法。

  

也可以说我有一个使用JSON.stringify(obj)的JSON字符串,是否有可能直接从第一个字符串创建与JSON.stringify(obj2)相对应的字符串?

是的,您可以将.toJSON添加到obj:

const obj = { "a": [1, 2], "b": [3, 4], "c": [5, 6] }
Object.setPrototypeOf(obj, {
    toJSON: function () {
        const result = []
        Object.keys(this).forEach(key => {
            this[key].forEach((value, index) => {
                if (!result[index]) {
                    result[index] = {}
                }
                result[index][key] = value
            })
        })
        return JSON.stringify(result);
    }
})



console.log(JSON.stringify(obj))

您可以使用Object.setPrototypeOf,以便在Object.keys(obj).forEach迭代时,toJSON方法不被视为可枚举的键

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

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior

答案 3 :(得分:0)

如果您的值(数组)具有相同的长度。

obj = {"a": [1,2],"b": [3,4],"c": [5,6]};
obj2 = [];

var keys = Object.keys(obj)

for (i = 0; i < obj[keys[0]].length; i++) {
    temp = {};
    keys.forEach(x => temp[x] = obj[x][i]);
    obj2.push(temp);
}

console.log(obj2);

答案 4 :(得分:0)

您可以遍历输入对象的键并使用Array.prototype.reduce

构造所需的输出

var obj={"a": [1,2],"b": [3,4],"c": [5,6]};

var result = Object.keys(obj).reduce((a, k) => (obj[k].forEach((n, i) => a[i] = {...(a[i] || {}), ...{[k]: n}}), a),[]);
  
console.log(result);

答案 5 :(得分:0)

您可以对键使用一个循环,对值使用另一个循环并映射一个新数组。

这适用于相同长度的数组。

var object = { a: [1, 2], b: [3, 4], c: [5, 6] },
    array = Object
        .entries(object)
        .reduce((r, [k, a]) => a.map((v, i) => Object.assign(r[i] || {}, { [k]: v })), []);
        
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }