将字符串数组转换为JS中的一个对象

时间:2018-10-21 13:28:02

标签: javascript object

假设我有以下数组:

[
 {
   path: ["info", "address", "city"]
 },
 {
   path: ["info", "first_name"]
 },
 {
   path: ["info", "last_name"]
 },
 {
   path: ["score"]
 }
]

我想将其转换为:

{
  personal_info: {
    first_name: some_value,
    last_name: some_value,
    adress: {
     city: some_value
    }
  },
  score: some_value
}

注意:some_value只是在路径键之前表示的另一个键。

我已经尝试过以下结构:

for(let i = a.length - 1; i >= 0 ; i--){
  if(i == a.length - 1)
    res = { [a[i]] : value};        // assign the value
  else
    res = { [a[i]] : res};          //put the prev object
}

但是我不知道如何从多个数组连接到一个对象。

4 个答案:

答案 0 :(得分:1)

您可以使用函数reduce或函数forEach来构建所需的输出。

这种方法使用函数reduce,对于特定的值,您需要决定如何设置它们。

let arr = [ {   path: ["info", "address", "city"] }, {   path: ["info", "first_name"] }, {   path: ["info", "last_name"] }, {   path: ["score"] }],
    value = 'some_value',
    personalInfoKey = 'personal_info',
    result = arr.reduce((a, {path}) => {  
      let [type, ...keys] = path;
      if (type === 'info') {
        if (keys.length === 1) a[personalInfoKey][keys.pop()] = value;
        else {
          a[personalInfoKey] = a[personalInfoKey] || {};
          let current = a[personalInfoKey];
          keys.forEach((k, i, ar) => current = current[k] = i === ar.length - 1 ? value : {});
        }
      } else a[type] = value;

      return a;
}, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

您可以使用2个reduce。第一个是通过数组循环。第二个是构造结果对象。

var arr = [
  {"path":["info","address","city"],"value":1},
  {"path":["info","first_name"],"value":2},
  {"path":["info","last_name"],"value":3},
  {"path":["score"],"value":4}
]

var result = arr.reduce((c, v) => {
  var t = v.path.reduce((a, o, i) => {
    o = o === "info" ? "personal_info" : o;
    if (i < v.path.length - 1 && !a[o]) a[o] = {};
    if (i < v.path.length - 1) return a[o];
    else return a;
  }, c);
  t[v.path[v.path.length - 1]] = v.value;
  return c;
}, {});

console.log(result);

答案 2 :(得分:1)

您可以迭代数组,并使用分配vlaue的默认对象减少键。

function setValue(object, path, value) {
    var last = path.pop();
    path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
    return object;
}

var data = [{ value: "Düsseldorf", path: ["info", "address", "city"] }, { value: "Jane", path: ["info", "first_name"] }, { value: "Smith", path: ["info", "last_name"] }, { value: 11000, path: ["score"] }],
    object = data.reduce((o, { path, value }) => setValue(o, [...path], value), {});

console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:0)

const data = [
 {
   path: ["info", "address", "city"]
 },
 {
   path: ["info", "first_name"]
 },
 {
   path: ["info", "last_name"]
 },
 {
   path: ["score"]
 }
];

const newObject = {};

function setValueByKeypath(currentObject, path, value) {
    for (let i = 0, len = path.length; i < len; i++) {
        const key = path[i];
        // if it is the last path part, add the value else we have to got on building objects
        const keyValue = (i === len - 1) ? value : {};
        // test if there is already a given key and if not create one or if it is the last part of the key add the value
        if (typeof currentObject[key] === "undefined") {
            currentObject[key] = keyValue;
        }
        currentObject = currentObject[key];
    }       
}

for (let i = 0, len = data.length; i < len; i++ ) {
    // build the nested path in the object by the given array data[i].path
    setValueByKeypath(newObject, data[i].path, "someValue");
}

console.log(newObject);

// create a reference 'personal_info' to 'info'
newObject.personal_info = newObject.info;
// delete the 'info' key
delete newObject.info;

console.log(newObject);

首先通过这些路径。然后将信息密钥转换为个人信息密钥。