javascript算法

84 阅读2分钟

列举一些面试可能会考到但是实际工作中使用频率较低的算法。

1、扁平数组转树形结构

const flatArray = [
    {id: 2, parentId: 1, name: 'child1'},
    {id: 1, parentId: null, name: 'root1'},
    {id: 3, parentId: 1, name: 'child2'},
    {id: 4, parentId: 2, name: 'grandchild1'},
    {id: 5, parentId: 4, name: 'grandchild2'},
    {id: 6, parentId: 5, name: 'grandchild3'},
    {id: 7, parentId: null, name: 'grandchild4'},
    {id: 8, parentId: 6, name: 'grandchild5'},
];

function arrayToTree(items) {
    // 存放结果集
    const result = []
    // 利用map结构,保存
    const map = {}
    for (const item of items) {
        map[item.id] = {...item}
    }

    for (const item of Object.values(map)) {
        // 因为数组元素子代的parentId === 父元素id,将父元素的id作为key保存到map里面
        // 然后通过子元素的parentId来查找对应关系
        if (map.hasOwnProperty(item.parentId)) {
            // 这里多加的判断是为了在没有子代元素的时候,不出现children属性
            if (map[item.parentId].hasOwnProperty('children')) {
                map[item.parentId].children.push(item)
            } else {
                map[item.parentId].children = [item]
            }
        } else {
            // parentId === null的肯定是一级菜单,可以直接在这里进行判断
            result.push(item)
        }
    }

    return result
}

console.time('arrayToTree')
const result1 = arrayToTree(flatArray)
console.timeEnd('arrayToTree')  // 0.1ms左右

2、树形结构转扁平数组

function treeToArray(tree) {
    const flatResult = []

    function innerFlat(arr) {
        arr.forEach(item => {
            const target = {...item}
            if (target.children) {
                innerFlat(target.children)
                delete target.children
            }
            flatResult.push(target)
        })
    }

    innerFlat(tree)

    return flatResult.sort((a, b) => a.id - b.id)
}

3、十进制转任意进制

const charsDict = '0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ-~'

function toAnySystem(chars, number) {
    const radix = chars.length  // 被转换的进制
    let qutient = +number, // 将要被转换的数字
        arr = [] //保存结果
    let mod
    do {
        // 对需要被转换的数字进行取余,这个是余数
        mod = qutient % radix;
        // 这个是商
        // 被取余之后这个数字一定可以被64整除,获取到取余之后的商
        // 如果这个数字大于64,那么qutient就不等于0,反之为0
        // 不等于0需要继续往前敬1,进入下一个循环,否则退出循环
        qutient = (qutient - mod) / radix;
        arr.unshift(chars[mod]);
    } while (qutient);
    return arr.join('');
}

const num = 9999

console.log(toAnySystem(charsDict, num)) // '2sf'

4、任意进制转换回十进制

function anyTo10System(num, dict) {
    let result = 0
    // 将字符串反转,因为二进制的字符串110转换为十进制可以理解成 0*2**0 + 1*2**1 + 1*2**2
    // 其它进制同理
    const numToArr = num.split('')
    let i = 0
    while (i < numToArr.length) {
        result += dict.indexOf(numToArr[i]) * dict.length ** (numToArr.length - 1 - i)
        i++
    }
    return result
}

const twoSystem = '2sf'

console.log(anyTo10System(twoSystem, charsDict)) // 9999