顺时针输出矩阵

1. 题目信息

输入:
    [
        [1, 2, 3],
        ['a', 'b', 'c'],
        [4, 5, 6]
    ]

输出:
    123c654ab
    
PS: 从外到里顺时针输出矩阵信息

2. 题目分析

做题原则: 只处理一种普遍的情况, 然后将其他情况变更为这种情况
数据1:

[
    [1, 2, 3, 4, 5],
    [1, 2, 3, 4, 5],
    [1, 2, 3, 4, 5],
    [1, 2, 3, 4, 5],
    [1, 2, 3, 4, 5],
]

数据2:

[
    [2, 3, 4],
    [2, 3, 4],
    [2, 3, 4],
]

观察上面2 个数据, 会发现: 其实数据2 是数据1的一种情况
数据1 - (处理完最外层数据) = 数据2

因此对于该题的处理思路是:

  1. 先处理最外层数据
    2, 删掉最外层数据, 得到一个全新的变量, 然后递归处理(回到第1步)
    递归跳出条件: 当数据变更成为 []

3. 代码

const log = console.log.bind(console)

const dealMatrix = (obj) => {
    let result = []
    let objLen = obj.length
    let innerLen = obj[0].length

    // 处理上边数据
    for (let i = 0; i < innerLen; i++) {
        result.push(obj[0][i])
    }

    // 处理右边数据
    for (let i = 1; i < objLen - 1; i++) {
        result.push(obj[i][innerLen - 1])
    }
    
    // 处理底部数据
    // 处理底部数据是: objLen - 1 !== 0; 为了防止底部数据和上边数同时处理, 这样同一组数据就处理了2遍
    if (objLen !== 1) {
        for (let i = innerLen - 1; i > -1; i--) {
            result.push(obj[objLen - 1][i])
        }
    }

    // 处理左边数据
    for (let i = objLen - 2; i > 0; i--) {
        result.push(obj[i][0])
    }

    let newObj = obj.slice(1, objLen - 1)
    newObj.forEach((ele) => {
        ele.pop()
        ele.shift()
    })

    return result
}

const __main = () => {
    let obj = [
        [1, 2, 3],
        ['a', 'b', 'c'],
        [4, 5, 6]
    ]
    // let obj = [
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // ]
    log(dealMatrix(obj))
}

__main()

4. 补充

下面一份是一个很厉害前辈的代码(其实非常年轻, 但是实力比自己厉害很多, 非常优秀的前辈), 这种代码真的彰显代码功力:

  1. 易懂, 思路清晰
  2. 熟练JavaScript 内置API, 简练处理数据

编程道路任重而道远, 多练!

const log = console.log.bind(console)

const sliceArray = (n) => {
    let len = n.length
    if (len <= 2) {
        return []
    }
    let result = []
    // forEach 循环 + 切片操作完成数据转换
    n.forEach((item, index) => {
        if (index !== 0 && index !== len - 1) {
            let l = item.length
            result.push(item.slice(1, l - 1))
        }
    })
    return result
}

const shunshizhen = (n) => {
    let inner = ''
    let head = ''
    let tail = ''
    let len = n.length
    if (len === 0) {
        return ''
    }
    // 一个for 循环解决了最外层的读取
    n.forEach((item, index) => {
        if (index === 0) {
            head = item.join('') // 处理矩阵的首行, 使用join 方法将数组处理成字符串
        } else if (index === len - 1) {
            tail = item.reverse().join('') + tail // 处理矩阵的末行, 使用reverse 方法配合join 方法将数组处理成顺序正确的字符串
        } else {
            head = head + item[item.length - 1] // 矩阵首行内容和矩阵右边内容集中处理
            tail = item[0] + tail //矩阵末行内容和矩阵左边内容集中处理, 这里这个顺序调用真的非常棒, 完美解决顺序问题
        }
    })

    let new_n = sliceArray(n)
    inner = shunshizhen(new_n)
    let result = head + tail + inner
    return result
}

const __main = () => {
    let obj = [
        [1, 2, 3],
        ['a', 'b', 'c'],
        [4, 5, 6]
    ]
    // let obj = [
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    // ]
    log(shunshizhen(obj))
}

__main()