二维数组之字形遍历

Zigzag traversal of a two-dimensional array

我需要以之字形遍历一个二维数组,并沿途挑选元素:

发件人:

[['','','',''],
 ['','','',''],
 ['','','',''],
 ['','','','']]

收件人:

['','','','','','','','','','','','','','','','']

我的方法是使用 for 循环,检查第一个数组的每个索引并将其与下一个数组的索引进行比较,然后如果该数字大一个,则将其推入新的一维数组。

解决此问题的最佳方法是什么?您是否有一些资源来了解有关此模式的更多信息?

更新的答案

此函数将以锯齿形方式合并数组。

这里我展示了 2 个具有不同数据类型值的数组的示例。

function zigZag(array) {
    let arrayLength = array.length;
    let arrayItemLength = array[0].length;
    let result = [];
    let flag = true;

    for(let i = 0; i < (arrayLength + (arrayLength / 2) + 1) ; i++) {
        if(i < arrayItemLength) {
            let length = (i + 1);
            let ii = i;
            for(let j = 0; j < length; j++) {
                if(flag == true) result.push(array[j][ii]);
                else result.push(array[ii][j]);
                ii-=1;
            }
        }else {
            let ii = (i + 1) - arrayItemLength;

            for(let j = arrayItemLength - 1; j > i - arrayItemLength; j--) {
                if(flag == true) result.push(array[ii][j]);
                else result.push(array[j][ii]);
                ii+=1;
            }
        }
        if(flag == true) flag = false;
        else flag = true;
    }

    return result;
}

let array = [
    ["" , "" , "" , "" ],
    ["" , "" , "" , "" ],
    ["" , "" , "" , "" ],
    ["" , "" , "" , "" ],
];

let array_1 = [
    [1, 3, 4, 10],
    [2, 5, 9, 11],
    [6, 8, 12, 15],
    [7, 13, 14, 16],
];

console.log(zigZag(array)); // icons
console.log(zigZag(array_1)); // numbers

旧答案

试试这个,我想这就是你想要做的。

let array = [
    [1, 3, 4, 10],
    [2, 5, 9, 11],
    [6, 8, 12, 15],
    [7, 13, 14, 16],
];

function mergeArray(array) {
    let merged = array.reduce((item, total) => [...total, ...item], []);
    return merged.sort((a, b) => a - b);
}

let result = mergeArray(array);

console.log(result)

旧答案:

您可以对 javascript 数组使用 .flat() 方法。 Array.flat()

let array = [
    [1, 3, 4, 10],
    [2, 5, 9, 11],
    [6, 8, 12, 15],
    [7, 13, 14, 16],
]
const flatArray = array.flat()
flatArray.sort((a,b)=>a-b)
console.log(flatArray)

更新答案: 问题更新输出后

const items = [
    [1, 3, 4, 10],
    [2, 5, 9, 11],
    [6, 8, 12, 15],
    [7, 13, 14, 16],
];

/*const items =  [
  [ ,  ,  ,  ],
  [ ,  ,  ,  ],
  [ ,  ,  ,  ],
  [ ,  ,  ,  ],
]*/

function zigZag(arr) {
    let array = []
    const itemCounts = arr.reduce((pre, cur)=> pre+cur.length,0)    
    for(let i=0; i<itemCounts; i+=1){
        let round = []
        for(let j=0; j<arr.length; j+=1){
            if(arr[j].length){
                round.push({
                    value: arr[j][0],
                    row:j
                })
            }
            
        }
        const minValue = Math.min(...round.map(item=>item.value))
        const target = round.find(item=>item.value == minValue)
        array.push(arr[target.row].shift())
    }    
    return array;
};

console.log(zigZag(items))

我的理解是你想转换一个n×n数组如:

[ ['', '', '', '']

, ['', '', '', '']

, ['', '', '', '']

, ['', '', '', ''] ]

进入:

['','','','','','','','','','','','','','','','']

让我们将原始数组转换为“位置矩阵”,然后尝试描绘“之字形”:

[ [[0,0], [0,1], [0,2], [0,3]]
// ↙      ↗      ↙      ↗
, [[1,0], [1,1], [1,2], [1,3]]
// ↗      ↙      ↗      ↙
, [[2,0], [2,1], [2,2], [2,3]]
// ↙      ↗      ↙      ↗
, [[3,0], [3,1], [3,2], [3,3]]
// ↗      ↙      ↗      ↙
]

如果我们关注边缘,我们就可以开始制定一个模式:

[ [0,0]
, [1,0], /* … */ [0,1]
, [2,0], /* … */ [0,2]
, [3,0], /* … */ [0,3]
, [3,1], /* … */ [1,3]
, [3,2], /* … */ [2,3]
,                [3,3] ]

现在我们需要计算出每条边之间的所有[x,y],并以相反的方向遍历每条边:

const inp1 = zigzag([ ['', '', '', '']

                    , ['', '', '', '']

                    , ['', '☝️', '', '']

                    , ['', '', '', ''] ]);

const inp2 = zigzag([ ['', '', '']

                    , ['', '', '']

                    , ['', '☝️', ''] ]);

const inp3 = zigzag([ ['', '']

                    , ['', ''] ]);

const inp4 = zigzag([ [''] ]);

console.log(`
  [${String(inp1)}]
  [${String(inp2)}]
  [${String(inp3)}]
  [${String(inp4)}]
`);
<script>
const zigzag = inp => {
  const m = inp.length - 1;
  const edges = [];
  for (let x = 0; x <= m; x++) edges.push([x, 0]);
  for (let x = 1; x <= m; x++) edges.push([m, x]);
  return edges.flatMap(([x, y], i) => {
    const path = [[x, y]];
    for (let a = x, b = y; a != y && b != x;) path.push([--a, ++b]);
    return (i % 2 ? path : path.reverse()).map(([x, y]) => inp[x][y]);
  });
}
</script>