Конвертировать массив массивов строк в один объект в JS - PullRequest
0 голосов
/ 21 октября 2018

Допустим, у меня есть следующий массив:

[
 {
   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 голосов
/ 21 октября 2018

Вы можете перебрать массив и уменьшить ключи с помощью объекта по умолчанию для назначения 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; }
0 голосов
/ 21 октября 2018

Вы можете использовать либо функцию 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; }
0 голосов
/ 21 октября 2018

Вы можете использовать 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);
0 голосов
/ 21 октября 2018

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

Сначала пройдите эти пути.А во-вторых, превратить информационный ключ в ключ personal_info.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...