将多个数组合并成JavaScript对象

7
是的,这个问题已经被回答了很多次,相信我,我在互联网上搜索过它。然而,经过相当长的时间,我还没有找到一个好的解决方案。
我的问题如下:
想象一下以下结构的数组:
[
  [ 'helpers', 'ConfigHelper.java' ],
  [ 'helpers', 'GenerateRandomString.java' ],
  [ 'helpers', 'package-info.java' ],
  [ 'helpers', 'ScreenshotHelper.java' ],
  [ 'pages', 'LoginPage.java' ],
  [ 'pages', 'package-info.java' ],
  [ 'pages', 'tests', 'LoginPageTest.java' ],
  [ 'pages', 'tests', 'package-info.java' ],
  [ 'pages', 'util', 'package-info.java' ],
  [ 'pages', 'util', 'PageObject.java' ],
  [ 'pages', 'util', 'PageObjectTest.java' ],
  [ 'pages', 'util', 'PrimaryMethods.java' ],
  [ 'webDriverSetup', 'browserDriverFactories', 'ChromeDriverFactory.java'],
]

你可以清楚地看到值的重复。我试图实现的是这样一个嵌套对象:
{
  helpers: {
    "ConfigHelper.java": "",
    "GenerateRandomString.java": "",
    "package-info.java": ""
  },
  pages: {
    "LoginPage.java": "",
    "package-info.java": "",
    tests: {
      "LoginPageTest.java": "",
      "package-info.java": ""
    },
    util: {
      "package-info.java": "",
      "PageObject.java": "",
      "PageObjectTest.java": "",
      "PrimaryMethods.java": ""
    }
  },
  webDriverSetup: {
    browserDriverFactories: {
      "ChromeDriverFactory.java": ""
    }
  }
}

每个数组值基本上都是另一个对象级别,除了最后一个值只有一个字符串作为其值。

一种有前途的方法是使用 array.reduce() 如下:

let arrays = [
  [ 'helpers', 'ConfigHelper.java' ],
  [ 'helpers', 'GenerateRandomString.java' ],
  [ 'helpers', 'package-info.java' ],
  [ 'helpers', 'ScreenshotHelper.java' ],
  [ 'pages', 'LoginPage.java' ],
  [ 'pages', 'package-info.java' ],
  [ 'pages', 'tests', 'LoginPageTest.java' ],
  [ 'pages', 'tests', 'package-info.java' ],
  [ 'pages', 'util', 'package-info.java' ],
  [ 'pages', 'util', 'PageObject.java' ],
  [ 'pages', 'util', 'PageObjectTest.java' ],
  [ 'pages', 'util', 'PrimaryMethods.java' ],
  [ 'webDriverSetup', 'browserDriverFactories', 'ChromeDriverFactory.java'],
];

let treeView = {};

arrays.forEach(array => {
  array.reduce(function(o, key) {
    return o[key] = {};
  }, treeView);
});

console.log(treeView);

然而,它显然总是会覆盖值,所以最后我会收到一个不完整的对象。
我的问题是:
如何编辑函数以便我收到一个完整的对象? 或者说 有哪些替代array.reduce()的方法?

也许这篇文章会解决你的问题: https://dev.to/trusktr/you-dont-need-arrayreduce-557f - Jefry90
在将 o[key] 转换为对象之前,请先测试它。 - Ibu
2
只需添加一个 if,检查元素/键是否已经存在于对象中,并采取相应措施。就像在 Stack Overflow 上的每个“如何对对象数组进行分组”的问题中所做的那样。如果第一层有效,则可以添加第二层(testsutil,...)。 - Andreas
2个回答

11

您可以使用此值作为键来保存最后一个值,然后将其余部分用于创建嵌套对象。

let arrays = [['helpers', 'ConfigHelper.java'], ['helpers', 'GenerateRandomString.java'], ['helpers', 'package-info.java'], ['helpers', 'ScreenshotHelper.java'], ['pages', 'LoginPage.java'], ['pages', 'package-info.java'], ['pages', 'tests', 'LoginPageTest.java'], ['pages', 'tests', 'package-info.java'], ['pages', 'util', 'package-info.java'], ['pages', 'util', 'PageObject.java'], ['pages', 'util', 'PageObjectTest.java'], ['pages', 'util', 'PrimaryMethods.java'], ['webDriverSetup', 'browserDriverFactories', 'ChromeDriverFactory.java']],
    treeView = arrays.reduce((tree, [...array]) => {
        var last = array.pop();
        array.reduce((o, k) => o[k] = o[k] || {}, tree)[last] = '';
        return tree;
    }, {});

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


谢谢。目前正在测试和尝试理解。 - Aaron von Schassen
虽然我个人认为比 Crani 的答案(也在评论中提到)更难阅读和理解,但它也考虑了最后一个值。感谢你们所有人。 - Aaron von Schassen
2
内部的 reduce 部分检查属性是否存在,并将其自身赋值或取对象作为默认值。实际对象引用作为新的累加器返回到下一次迭代,或者作为分配 last 属性的结果。 - Nina Scholz
1
@NinaScholz 这行代码 array.reduce((o, k) => o[k] = o[k] || {}, tree)[last] = ''; 将结果赋值给了 tree 吗?你能否写一个简化版的版本,适合初学者理解吗?你的回答真的很棒,我真的想理解它。 - Learner
3
final = array.reduce((o, k) => { if (!o[k]) o[k] = {}; return o[k]; }, tree); final[last] = '';这段代码的作用是将一个名为 array 的数组转化为一个嵌套对象 tree,并将 tree 对象中某个属性 last 的值设置为空字符串。具体实现方式是使用数组的 reduce() 方法迭代处理数组元素,每次迭代都会将当前元素作为对象属性名,在 tree 对象上创建一层新的嵌套对象,并返回该对象。在最后一次迭代结束后,使用 final[last] = ''tree 对象中的某个属性 last 置为空字符串。需要注意的是,该代码可能会改变原始输入数组 array 的内容。 - Nina Scholz

2

只需检查对象键是否已存在。

let treeView = {};

arrays.forEach(array => {
  array.reduce(function(o, key) {
    if (!treeView[key]) {
      return (o[key] = {});
    } else {
      return (o[key] = treeView[key]);
    }
  }, treeView);
});

console.log(treeView);

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