将对象文字转换为包含路径的对象?

时间:2017-01-31 15:55:51

标签: javascript lodash

我想要获取一个对象字面值,并将其转换为新对象键所在的新对象。

const obj = {
  test: {
    qwerty: 'text',
    abc: {
      testing: 123
    }
  }
}

要:

{
  'test.qwerty': 'text',
  'test.abc.testing': 123
}

我一直在浏览lodash docs,但我看不到任何可能很快发生的事情。

对象文字可以是任意数量的级别。

最好的方法是什么?

3 个答案:

答案 0 :(得分:1)

不知道lodash是否有任何内置函数,但这是一种使用ES6 arrow functions,可选参数和递归调用的方法:

const obj = {
  test: {
    qwerty: 'text',
    abc: {
      testing: 123
    }
  }
}


pathMyObject = (obj, prefix, newObj = {}) => {
    Object.keys(obj).forEach( key => {
        const value = obj[key];
        const newPrefix = (!prefix ? key : prefix + "." + key)
        if (typeof value === 'object') {
            pathMyObject(value, newPrefix, newObj)
        } else {
            newObj[newPrefix] = value;
        }
    })
    return newObj
}

const path = pathMyObject(obj);

console.log(path);
/*
  { 
    'test.qwerty': 'text', 
    'test.abc.testing': 123 
  }
*/

答案 1 :(得分:1)

这是使用Lodash reduce函数的递归函数。



const obj = {
  test: {
    qwerty: 'text',
    abc: {
      testing: 123
    }
  }
};

function toPaths(obj, path) {
  if (typeof obj !== 'object') { return { [path]: obj }; }
  return _.reduce(obj, (result, value, key) =>
    Object.assign({}, result, toPaths(value, path ? `${path}.${key}` : key))
  , {});
}

console.log(toPaths(obj));

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
&#13;
&#13;

它只比非Lodash等同物略显冗长:

&#13;
&#13;
const obj = {
  test: {
    qwerty: 'text',
    abc: {
      testing: 123
    }
  }
};

function toPaths(obj, path) {
  if (typeof obj !== 'object') { return { [path]: obj }; }
  return Object.keys(obj).reduce((result, key) =>
    Object.assign({}, result, toPaths(obj[key], path ? `${path}.${key}` : key))
  , {});
}

console.log(toPaths(obj));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以创建递归函数来构建这样的对象。

const obj = {
  test: {
    qwerty: 'text',
    abc: {
      testing: 123
    }
  }
}

function toStrings(data) {
  var r = {}

  function inner(data, c) {
    for (var i in data) {
      if (typeof data[i] == 'object') inner(data[i], c + i + '.')
      else r[(c + i).replace(/\.$/, "")] = data[i]
    }
  }
  inner(data, '');
  return r;
}

console.log(toStrings(obj))