bibi7 / fe-daily-increase

一个记录开发日常和奇奇怪怪的点的repo
MIT License
5 stars 0 forks source link

请把俩个数组 [A1, A2, B1, B2, C1, C2, D1, D2] 和 [A, B, C, D],合并为 [A1, A2, A, B1, B2, B, C1, C2, C, D1, D2, D]。 #38

Open bibi7 opened 5 years ago

bibi7 commented 5 years ago

其实第一眼看到这个题目的时候,大概是想用code码来做的,因为我依稀记得charCodeAt的用法,于是有如下东西:

function concatArray(arr1, arr2) {
  arr2.forEach((item, index) => {
    let currentIndex = 0;
    while (arr1[currentIndex]) {
      if (item.charCodeAt() < arr1[currentIndex].charCodeAt()) {
        arr1.splice(currentIndex, 0, item);
        break
      }
      currentIndex++
    }
  })
  return arr1
}

从逻辑上看,判断下一个code码大于本次插入的code,则插入。但是细想后发现其实有点问题,因为当数组遍历到最后一位的时候,判定条件已经是超了边界的:

concatArray(['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'], ['A', 'B', 'C', 'D'])

["A1", "A2", "A", "B1", "B2", "B", "C1", "C2", "C", "D1", "D2"]

那可以换种思路嘛,从后一位判定会超出判定边界的话,那么可以从前面来判定:

function concatArray(arr1, arr2) {
  arr2.forEach((item, index) => {
    let currentIndex = 0;
    let strIndex = 0;
    while (arr1[currentIndex]) {
      if (arr1[currentIndex].indexOf(item) !== -1) {
        strIndex = currentIndex
      }
      currentIndex++
    }
    arr1.splice(strIndex + 1, 0, item)
  })
  return arr1
}

看了一圈大佬的答案,发现还是有很多值得借鉴的地方,继续总结一些其他解法。

startsWith的方式。总体思路和第一种都是一样的,都需要遍历全部的数组得出最终的插入index:

function concatArray(arr1, arr2) {
    let currentItem = arr2.shift();
    while (currentItem) {
        let currentIndex = 0;
        for (let i = 0; i < arr1.length; i++) {
            if (arr1[i].startsWith(currentItem)) {
                currentIndex = i;
            }
        }
        arr1.splice(currentIndex + 1, 0, currentItem)
        currentItem = arr2.shift()
    }
    return arr1
}

filter拆分数组的方式:

const arr1 = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'];
const arr2 = ['A', 'B', 'C', 'D'];

function concatArray(arr1, arr2) {
  let result = arr2.map(item => {
    const filterArray = arr1.filter(val => val.startsWith(item))
    return [...filterArray, item]
  })

  return [].concat(...result)
}

concatArray(arr1, arr2)

鬼才解法,老哥666:

function concatArray(arr1, arr2) {
    const array = arr2.map(item => item + '3')
    const result = [...arr1, ...array].sort().map(item => {
        if (item.indexOf('3') !== -1) {
            return item.split('')[0]
        }
        return item
    })

    return result
}

看到最高级的解法了目前:

let arr1 = ["A1", "A2", "B1", "B2", "C1", "C2", "D1", "D2"];
let arr2 = ["A", "B", "C", "D"];
console.log(
  [...arr1, ...arr2]
    .sort(
      (v2, v1) => (
        v2.codePointAt(0) - v1.codePointAt(0) ||
        v1.length - v2.length ||
        v2.codePointAt(1) - v1.codePointAt(1)
      )
    )
);
  1. 后面的字母的chartCode码必然比前面大,所以为负数则调换位置。
  2. 第二位数字逻辑一样
  3. A需要在A1后面,则负数的话需要把length最小的挪到最后面
bibi7 commented 5 years ago

讨论地址