【问题标题】:Iterating over rows of 2-dimensional array containing arrays of different length迭代包含不同长度数组的二维数组行
【发布时间】:2016-07-07 22:43:52
【问题描述】:

我有一个函数,它按行从二维数组中挑选所有元素并返回一个一维数组。 该数组具有可变数量的列和行。

例子:

let arr = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
];

返回:

[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]

我想出的功能:

convertList = (list) => {
    let result = [];
    let listTotalEntries = R.sum(R.map(R.length)(list));
    let mod = R.modulo(R.__, list.length);

        let counterRow = -1;

        for (let i = 0; i < listTotalEntries; i++) {
            if (mod(i) === 0) {
                counterRow++;
            }
            if (list[mod(i)][counterRow]) {
                result.push(list[mod(i)][counterRow]);
                console.log(list[mod(i)][counterRow]);
            }
        }
        console.log(result);
        return result;
};

问题:此函数仅适用于方阵 - 如何使其适用于包含的数组的可变长度?

例子:

let arr = [
    [1, 2],
    [],
    [9, 10, 11, 12]
];

应该返回:

[1, 9, 2, 10, 11, 12]

感谢您的帮助!

马夫

【问题讨论】:

    标签: javascript arrays multidimensional-array ramda.js


    【解决方案1】:

    你在这里有一个ramda.js 标签。使用 Ramda,这非常简单,因为有两个函数会有所帮助:

    const convertList = compose(flatten, transpose);
    convertList(arr); //=> [1, 9, 2, 10, 11, 12]
    

    transpose 将矩阵翻转到其主对角线上,即将行更改为列,反之亦然。 flatten 将列表列表转换为普通列表。所以像这样composeing 本质上创建了list =&gt; flatten(transpose(list)) 的等价物。

    您可以在 Ramda REPL 上看到这一点。

    【讨论】:

    • 哇!像魅力一样工作,精益整洁!我没有意识到 Ramda 中存在像转置这样的功能 - 内化所有功能和相关可能性需要一些时间和经验。谢谢!
    • 是的,Ramda 团队正在努力改进发现函数的方法。其中一个步骤是just published yesterday
    • 太棒了! 已添加书签 - 我期待手册/指南的进展。我找到了一个 0.17 版,但似乎只有介绍性章节可用。我希望他们继续写它作为对文档的适当补充。
    • 这已经被搁置了,但我们希望能尽快恢复。顺便说一句,虽然它在特定版本下列出,但它确实相当通用。
    【解决方案2】:

    我建议逐步遍历数组

    var arr1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
        arr2 = [[1, 2], [], [9, 10, 11, 12]];
    
    function single(array) {
        var r = [],
            max = Math.max.apply(null, array.map(function (a) { return a.length; })),
            i = 0, j,
            l = array.length;
    
        while (i < max) {
            for (j = 0; j < l ; j++) {
                i in array[j] && r.push(array[j][i]);
            }
            i++;
        }
        return r;
    }
    
    document.write('<pre>' + JSON.stringify(single(arr1), 0, 4) + '</pre>');
    document.write('<pre>' + JSON.stringify(single(arr2), 0, 4) + '</pre>');

    【讨论】:

    • 谢谢 - 我赞成您的解决方案并检查了 James 的解决方案,因为它更紧凑并使用 reduce 和 filter。
    • @Raggamuffin,它可能看起来更紧凑,但不一定比 while 循环和 for 循环执行得更好。
    【解决方案3】:

    你试过这个简单的吗?

    var singleDimensionArr = arr.reduce(function(prev,current){return prev.concat(current)});
    

    例如

    [
        [1, 2],
        [],
        [9, 10, 11, 12]
    ].reduce(function(prev,current){return prev.concat(current)});
    

    输出[1, 2, 9, 10, 11, 12]

    编辑:

    基于下面 OP 的输入,因为串联需要逐列进行

    var max = Math.max.apply(null, arr.map(function (a) { return a.length; }));
    var finalArr = []; for( var i = 0; i < max; i++)
    {
       for( var j = 0; j < arr.length; j++)
       {
           arr[j][i] ? finalArr.push(arr[j][i]) : "";
       }
    }
    console.log(arr);
    

    【讨论】:

    • 这与OP添加的结果不匹配
    • 对不起,我在退货声明中有错字,9 和 2 翻转的地方我更正了。您的解决方案按列挑选项目 - 我想按行挑选项目。
    • @Marie 因为有一个错字(这完全改变了问题)。
    • 现在你和我的回答基本一样,但你不会返回虚假值,例如0
    • @NinaScholz 是的,我无法评价你对max 的评价。如果你愿意,你可以为我投反对票:)
    【解决方案4】:

    这个例子创建了一个大的稀疏数组,如果数组是方形的,则将每个项目放在它所属的位置。然后它会过滤掉在没有输入项的情况下出现的空值。

    let arr = [
        [1, 2],
        [],
        [9, 10, 11, 12]
    ];
    
    var out = arr.reduce(function(o,n,i,a) {
      for (var j=0;j<n.length;j++){
        o[a.length * j + i] = n[j];
      }
      return o;
    },[]).filter(function(n) {
      return n !== null;
    });
    
    alert(JSON.stringify(out));

    【讨论】:

      猜你喜欢
      • 2012-04-20
      • 2014-04-23
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 2018-10-13
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多