将单维数组转换为多维数组

4
在Javascript中,如何将单维数组转换为未指定深度或长度的多维数组。
示例:
let input = ['a','b','b','b','a','a','b','b','b','c','c','a','a','b','b'];
const makeMatrix = () => {}

let output = makeMatrix(input);

// output: ['a',['b','b','b'],'a','a',['b','b','b',['c','c']],'a','a',['b','b']]

假设值总是沿线性向前移动,但可能会向后切割。因此,a总是引导到b。 a永远不会跳到c。但c可能会回到a,那么makeMatrix函数应该是什么样子才能完成这个任务呢?
这是为了将标题元素转换为目录。制作一个简单的单层目录很容易,但制作多层目录让我费尽心思。我查看了许多解决方案,但没有看到任何解决这个特定问题的东西。

一个包含数字数组的解决方案对你是否有用? - Jack Bashford
转换输入的过程是什么?看起来你想让'a'在1级,'b'在2级,'c'在3级等等。如果是这样,我认为最简单的方法就是创建一个以"["开头的字符串,跟踪您所在数组的当前深度(从1开始),并在每个字符上添加"["或"]",以使您处于正确的级别,然后将字符包装在''中添加到字符串中,并在最后将字符串评估为数组。 - Countingstuff
@Countingstuff 如果您能够制作出这个解决方案,我很想看看它。 - bronkula
@zfrisch 这些只是示例,我将通过节点名称迭代遍历HTML元素。但解决这个问题的方法应该也是解决那个问题的方法。 - bronkula
@bronkula明白了 - zfrisch
显示剩余3条评论
3个回答

4
你可以使用一个 level 变量和一个 levels 数组来推入未知元素。

var input = ['a', 'b', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'a', 'a', 'b', 'b'],
    levels = [[]],
    level = 0,
    result;

input.forEach(v => {
    var l = level;
    do {
        if (levels[l][0] === v) {
            level = l;
            levels[level].push(v);
            return;
        }
    } while (l--)
    levels[level].push(levels[level + 1] = [v]);
    level++;
});

result = levels[0][0];

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


哈哈,比我的愚蠢的评估工具好多了:D。 - Countingstuff
每次我回到这个答案时,它都有一点变化。 - bronkula
1
@bronkula,我改变了内部循环的结构,现在它从层级循环到零。循环比以前简单得多。 - Nina Scholz

3
我原本想到的愚蠢的eval解决方案,如果这是你想要的,它可以变得简洁...
function toMulti(arr) {
    let str = "[";
    let level = 1;
    const charLevels = { a: 1, b: 2, c: 3 };
    arr.forEach(char => {
        const charLevel = charLevels[char];
        if (level < charLevel) {
            for (let i = 0; i < charLevel - level; i++) {
                str += "[";
            }
        }
        if (level > charLevel) {
            for (let i = 0; i < level - charLevel; i++) {
                str += "],";
            }
        }
        level = charLevel;
        str += `'${char}',`;
    });
    for (let i = 0; i < level; i++) {
        str += "]";
    }
    return eval(str);
}

2

使用JSON构建/解析的替代版本:

const input = ['a', 'b', 'b', 'b', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'a', 'a', 'b', 'b'];

const result = JSON.parse(Object.entries(input).reduce((json, [key, val]) => {
  const jsonVal = JSON.stringify(val);
  const diff = key > 0 ? val.charCodeAt(0) - input[key - 1].charCodeAt(0) : 0;
  if (diff > 0) {
    json += ',['.repeat(diff) + jsonVal;
  } else if (diff < 0) {
    json += ']'.repeat(-diff) + ',' + jsonVal;
  } else {
    json += (key > 0 ? ',' : '') + jsonVal;
  }
  return json;
}, '[') + ']'.repeat(input.slice(-1)[0].charCodeAt(0) - input[0].charCodeAt(0) + 1));

console.log(result);

这基本上是使用Array.reduce在输入数组上构建JSON字符串,将每个项目相加并比较键代码以在此过程中包含正确数量的开放/关闭括号。


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