二维数组的之字形遍历

3
我需要沿着之字形遍历一个二维数组,并挑选沿途的元素:
从:
[['','','',''],
 ['','','',''],
 ['','','',''],
 ['','','','']]

To:

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

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

如何解决此问题最佳方法是什么?你有什么资源可以了解更多关于这种模式的内容吗?


好的,等一下我会尝试去做。数组中是否可能包含重复的条目? - Sparrow
是的,你说得对。 - Alan
你真的认为你所接受的答案是正确的吗? - Sparrow
@Alan,你问的是Zigzag方法,对吗? - Sparrow
是的,Zigzag方法 - Alan
3个回答

0

更新的答案

此函数将以zigZag方式合并数组。

这里我展示了具有不同数据类型值的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)


但是这只是按递增顺序对数组进行排序,挑战在于根据之字形方式对数组进行排序。 - Alan
@Alan,实际上你的问题很好,但不知道为什么有人给你点了踩。 - Sparrow

0

旧答案:

你可以使用 .flat() 方法来处理 javascript 数组。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)

UPDATE ANSWER: after question update output

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))


哦,谢谢你告诉我关于 flat 函数的事情。 - Sparrow
1
但是这只是按递增顺序对数组进行排序,挑战在于根据之字形方式对数组进行排序。 - Alan
@Alan 哦,之字形路径。好的,但从你的输出来看,我觉得它不是之字形。你的输出正确吗? - Amin Taghikhani
是的,你说得对,输入和输出可能会让人感到困惑,我将其更改以更好地理解问题。 - Alan
1
@Alan 谢谢,这样更好。我会更新我的答案并通知你。 - Amin Taghikhani
@Alan,我的回答已更新,请使用数字值作为答案。 - Amin Taghikhani

0

我的理解是您想要转换一个 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>


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