@lexstile

Как из плоского объекта с ключами, которые представляют собой несколько ключей склеенных через точку, сделать вложенный объект?

Есть объект input - то, что дано.
Нужно из него сделать объект output.

const input = {
  'foo.0.first': 111,
  'foo.1.first': 222,
  'bar.second': 333,
};

const output = {
  foo: [{ first: 111 }, { first: 222 }],
  bar: { second: 333 }
};
  • Вопрос задан
  • 322 просмотра
Решения вопроса 5
NeiroNx
@NeiroNx
Программист
Фигурные скобочки в JS - тип данных Object, нужные значения в ключах значит берем Object.keys(input) и перечисляем все элементы. Далее текст разбиваем на подстроки через split и проходимся по массиву присваивая значения.
Ответ написан
0xD34F
@0xD34F Куратор тега JavaScript
function setVal(obj, path, val) {
  const keys = path.split('.');
  const key = keys.pop();
  keys.reduce((p, c) => p[c] = p[c] || {}, obj)[key] = val;
  return obj;
}

function replaceObjWithArr(obj) {
  if (obj instanceof Object) {
    const keys = Object.keys(obj).sort((a, b) => a - b);
    obj = keys.every((n, i) => +n === i) ? keys.map(n => obj[n]) : obj;
    keys.forEach(n => obj[n] = replaceObjWithArr(obj[n]));
  }

  return obj;
}


const output = replaceObjWithArr(Object
  .entries(input)
  .reduce((acc, n) => setVal(acc, ...n), {})
);
Ответ написан
Комментировать
lastuniverse
@lastuniverse
Всегда вокруг да около IT тем
Когда то делал что то подобное . Нужная вам логика в функции parsePermissions

PS: вот поубирал лишнее и сделал демку (на выходе почти то что вы хотели). в самой функции parsePermissions тоже многое можно поубирать, но тут уж сами немного поработайте))))
тык
{
᠌ ᠌᠌ ᠌ ᠌ "foo": {
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ "0": {
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ "first": 111
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ },
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ "1": {
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ "first": 222
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ }
᠌ ᠌᠌ ᠌ ᠌ },
᠌ ᠌᠌ ᠌ ᠌ "bar": {
᠌ ᠌᠌ ᠌ ᠌ ᠌ ᠌᠌ ᠌ ᠌ "second": 333
᠌ ᠌᠌ ᠌ ᠌ }
}





PPS: и вот еще вариантик, но тоже на стал превращать объекты в массивы)))
тык

const insert = (target,path,value) => path.split(".").reduce((a,k,i,l)=>a[k]=i+1==l.length?value:a[k]||{},target);

const parse = (list,result={}) => Object.keys(list).forEach(k=>insert(result,k,list[k]))||result;

const output = parse(input);
Ответ написан
Комментировать
@nvdfxx
Senior Pomidor developer
const getOutput = input => {
  let obj = {}
  for(key in input) {
    let keyArr = [...key.split('.')]
    if(obj[keyArr[0]]) {
      obj[keyArr[0]].push({[keyArr[keyArr.length - 1]]: input[key]})
    } else {
      obj[keyArr[0]] = [{[keyArr[keyArr.length - 1]]: input[key]}]
    }
  }
  for(key in obj) {
    if(obj[key].length === 1) obj[key] = obj[key][0]
  }
  return obj
}
Ответ написан
Комментировать
@tansur
function createObject(input) {
    let output = {}
    Object.keys(input).map((item, idx) => {
        let inputValue = input[Object.keys(input)[idx]],
            arr = item.split('.'),
            [mainKey, subKey] = arr;
        if (typeof output[mainKey] === 'undefined') output[mainKey] = arr.length > 2 ? [] : {};

        if (Array.isArray(output[mainKey])) {
            let obj = new Object();
            obj[subKey] = inputValue;
            output[mainKey].push(obj);
        } else {
            output[mainKey][subKey] = inputValue;
        }
    });
    return output;
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Fragster
@Fragster
помогло? отметь решением!
Поможет Object.keys()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы