如何在JavaScript中从数组键列表中创建一个子关联对象?

问题描述 投票:0回答:1

我有一个来自用户输入的对象。该对象的键用逗号隔开,我只是想把这些键分开,并使该对象的键。

这个 key_array 下面是根据用户输入动态生成的,每次都会生成不同的数组,下面我给大家举个例子.我已经在我的代码中展示了对象,大家可以在下面看到.大家也可以通过运行该代码看到输出。

var main_array = {};
var key_array = {
    'user,name' : 'user name',
    'user,email' : 'Email address',
    'order,id' : 123456,
    'order,qty' : 2,
    'order,total' : 300,
    'order,product,0,name' : "product1",
    'order,product,0,qty' : 1,
    'order,product,0,price' : 100,
    'order,product,1,name' : "product2",
    'order,product,1,qty' : 1,
    'order,product,1,price' : 200,
};

for (keys in key_array){
    var value = key_array[keys];

    // What do I do here to get the output I want?
    main_array['[' + keys.split(",").join('][')+ ']'] = value;
}
console.log(main_array);

运行上面的代码会给你下面的输出,这是不正确的。而且是我不想要的输出。

{
    [order][id]: 123456,
    [order][product][0][name]: "product1",
    [order][product][0][price]: 100,
    [order][product][0][qty]: 1,
    [order][product][1][name]: "product2",
    [order][product][1][price]: 200,
    [order][product][1][qty]: 1,
    [order][qty]: 2,
    [order][total]: 300,
    [user][email]: "Email address",
    [user][name]: "user name"
}

我想要的是像下面JSON这样的输出,所以请告诉我怎么做。

{
    "user":{
        "email" : "Email address",
        "name"  : "user name"
    },
    "order":{
        "id"    : 123456,
        "qty"   : 2,
        "total" : 300,
        "product":[
            {
                "name"  : "product1",
                "price" : 100,
                "qty"   : 1
            },{
                "name"  : "product2",
                "price" : 200,
                "qty"   : 1
            }
        ]
    }
}

注意:请不要使用 eval,因为使用 eval 这样的方式是非常不可靠的,工作不好,也不安全。因为我所有的数据都来自用户输入,所以滥用的可能性会增加。

javascript arrays object associative-array
1个回答
0
投票
  1. 使用 Object.entries 来查看对象的键和值。
  2. 拆分 key, 分隔符,然后建立对象。
  3. 在构建对象时,请确保使用以下方法合并键和值 mergeTo 方法进行转换。
  4. 然后将有数字键的对象转换为对象,然后使用 convertObjsToArray 方法。

var key_array = {
  "user,name": "user name",
  "user,email": "Email address",
  "order,id": 123456,
  "order,qty": 2,
  "order,total": 300,
  "order,product,0,name": "product1",
  "order,product,0,qty": 1,
  "order,product,0,price": 100,
  "order,product,1,name": "product2",
  "order,product,1,qty": 1,
  "order,product,1,price": 200
};

const mergeTo = (target, obj) => {
  Object.entries(obj).forEach(([key, value]) => {
    if (typeof value === "object" && !Array.isArray(value)) {
      if (!target[key]) {
        target[key] = {};
      }
      mergeTo(target[key], obj[key]);
    } else {
      target[key] = value;
    }
  });
};

const convertObjsToArray = obj => {
  Object.entries(obj).forEach(([key, value]) => {
    if (typeof value === "object") {
      if (Object.keys(value).every(num => Number.isInteger(Number(num)))) {
        obj[key] = Object.values(value);
      } else {
        convertObjsToArray(obj[key]);
      }
    }
  });
};

const res = {};
Object.entries(key_array).map(([key, value]) => {
  const keys = key.split(",");
  let curr = { [keys.pop()]: value };
  while (keys.length > 0) {
    curr = { [keys.pop()]: curr };
  }
  mergeTo(res, curr);
});
convertObjsToArray(res);

console.log(res);

0
投票

你可以从字符串中动态地创建所需的对象和键,取每个键并使用 split(','). 使用数组中的每一个项目创建所需的结构。假设如果一个键是一个数字,那么它的父项必须是一个数组。

Object.keys(key_array).forEach(key => {
    const path = key.split(',');
    let current = main_array;

    for (let i = 0; i < path.length - 1; i++) {
        if (!current[path[i]]) {
            current[path[i]] = path[i + 1] && !isNaN(path[i + 1]) ? [] : {};
        }
        current = current[path[i]];
    }
    current[path.pop()] = key_array[key];
});

console.log(main_array); // Desired result
© www.soinside.com 2019 - 2024. All rights reserved.