基于字符串值的数组在对象中创建一个对象

6

我需要根据字符串值的数组更新对象名称,而最后一个字符串值应该是一个数组。

我使用array.forEach循环,但我不知道如何查找对象内部的对象(如果存在),而且myArray大约包含10,000个字符串。

const myArray = [
  '/unit/unit/225/unit-225.pdf',
  '/nit/nit-dep/4.11/nit-4.11.pdf',
  '/nit/nit-dep/4.12/nit-4.12.pdf',
  '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf',
  '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'
];
var parentObject = {}
myArray.forEach(res => {
  res = res.slice(1, res.length);
  var array = res.split("/");
  array.forEach((e, i) => {
    ........ // here I am confused 

  });
})

最终输出的结果应该是:

parentObject = {
  'unit': {
    'unit': {
      '225': {
        'unit-225.pdf': []
      }
    }
  },
  'nit': {
    'nit-dep': {
      '4.11': {
        'nit-4.11.pdf': []
      },
      '4.12': {
        'nit-4.12.pdf': []
      }
    }
  },
  'org': {
    'viti': {
      'viti-engine': {
        '5.1': {
          'viti-engine-5.1.pdf': []
        }
      },
      'viti-spring': {
        '5.2': {
          'viti-engine-5.2.pdf': []
        }
      }
    }
  }
}
3个回答

3

将字符串通过斜杠分割后,使用 reduce 方法迭代到嵌套对象中,如有必要则先创建每个嵌套属性,然后将数组赋值给文件名属性:

const myArray = [
  '/unit/unit/225/unit-225.pdf',
  '/nit/nit-dep/4.11/nit-4.11.pdf',
  '/nit/nit-dep/4.12/nit-4.12.pdf',
  '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf',
  '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'
];
var parentObject = {}
myArray.forEach((str) => {
  const props = str.slice(1).split('/');
  const filename = props.pop();
  const lastObj = props.reduce((a, prop) => {
    if (!a[prop]) {
      a[prop] = {};
    }
    return a[prop];
  }, parentObject);
  lastObj[filename] = [];
});
console.log(parentObject);


2
你可以缩小数组并缩小路径。最后将数组赋值。

const
    array = ['/unit/unit/225/unit-225.pdf', '/nit/nit-dep/4.11/nit-4.11.pdf', '/nit/nit-dep/4.12/nit-4.12.pdf', '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf', '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'],
    result = array.reduce((r, path) => {
        var keys = path.split(/\//).slice(1),
            last = keys.pop();

        keys.reduce((o, k) => o[k] = o[k] || {}, r)[last] = [];
        return r;
    }, {});

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

一个稍微更快的方法。

const
    array = ['/unit/unit/225/unit-225.pdf', '/nit/nit-dep/4.11/nit-4.11.pdf', '/nit/nit-dep/4.12/nit-4.12.pdf', '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf', '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'],
    result = {};

for (let path of array) {
    let keys = path.split(/\//).slice(1),
        last = keys.pop(),
        temp = result;

    for (let key of keys) {
        temp[key] = temp[key] || {};
        temp = temp[key];
    }
    temp[last] = [];
}

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


0

你也可以采用递归的方法。

只需不断地移动分割路径,直到获得每个分支的最终赋值。

const myArray = [
  '/unit/unit/225/unit-225.pdf',
  '/nit/nit-dep/4.11/nit-4.11.pdf',
  '/nit/nit-dep/4.12/nit-4.12.pdf',
  '/org/viti/viti-engine/5.1/viti-engine-5.1.pdf',
  '/org/viti/viti-spring/5.1/viti-spring-5.1.pdf'
];

console.log(buildTree(myArray));

function buildTree(list=[]) {
  return list.reduce((node, item) => buildBranches(node, item.split(/\//g).filter(x => x !== '')), {});
}

function buildBranches(node={}, rest=[]) {
  let key = rest.shift();
  node[key] = rest.length < 2 ? { [rest.shift()] : [] } /** or rest.shift() */ : node[key] || {};
  if (rest.length > 1) buildBranches(node[key], rest);
  return node;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接