Javascript 数组常用算法

2,332 阅读2分钟

数组去重

filter 方法实现

// 0.0.2/arrayUniqueFilter.js
const arr = [1, 2, 11, 22, 11, 1, 11, 22, 1, 2];
const unique = arr => arr.filter((element, index, self) => {
    // self.indexOf(element) 每次都从数组第一个元素开始往下查
    return self.indexOf(element) === index;
});
console.log(unique(arr)); // [1, 2, 11, 22]

// 上面可简写为
const unique2 = arr => arr.filter((element, index, self) => self.indexOf(element) === index);
console.log(unique2(arr)); // [1, 2, 11, 22]

// 元素非对象
const arr3 = [
    { id: 1, name: '张三' },
    { id: 2, name: '李四' },
    { id: 11, name: '王五' },
    { id: 1, name: '张三' },
    { id: 11, name: '王五' },
    { id: 3, name: '李四' }
];
const unique3 = (arr, id) => {
    let cache = [];
    for(let item of arr){
        if(cache.find(v => v[id] === item[id])) {
            continue;
        }
        cache.push(item);
    }
    return cache;
}
console.log(unique3(arr3, 'id')); // [{id: 1, name: "张三"}, {id: 2, name: "李四"}, {id: 11, name: "王五"}, {id: 3, name: "李四"}]

reducer 方法实现

// 0.0.2/arrayUniqueReducer.js
const unique = arr => arr.sort().reduce((cache, current) => {
    if(cache.length === 0 || cache[cache.length -1] !== current){
        cache.push(current);
    }
    return cache
}, []);

const arr = [1, 2, 11, 22, 11, 1, 11, 22, 1, 2];
console.log(unique(arr));

数组降维

// 0.0.2/arrayDimensionalityReduction.js
const arr = [1, [ 1, 2, [2, 3]], [3, 4], 5];
const arrayDimensionalityReduction = arr => Array.isArray(arr) ? 
    arr.reduce((prev, cur) => [...prev, ...arrayDimensionalityReduction(cur)], []) :
    [arr];

console.log(arrayDimensionalityReduction(arr)); // [1, 1, 2, 2, 3, 3, 4, 5]

数组交集

// 0.0.2/array_algorithms.js
const arr1 = [1, 7, 4, 5, 2, 1, 5, 3, 6, 2, 1, 3,];
const arr2 = [2, 4, 3, 4, 5, 5, 5];

const intersection = (arr1, arr2) => {
    const map = new Map();
    const arr = [];
    // 键值对,键是 value,值是 value 出现次数, 出现次数累加
    for (let i = 0; i < arr1.length; i++) {
        const value = arr1[i];
        let valueInMap = map.get(value);
        valueInMap = (valueInMap ? valueInMap : 0) + 1
        map.set(value, valueInMap)
    }
    // 键值对,中转 map 判断第二个数组的值是否存在,存在就留下来,然后 map 值次数减1
    for (let i = 0; i < arr2.length; i++) {
        const value = arr2[i];
        if (map.has(value) && map.get(value) !== 0) {
            arr.push(value);
            map.set(value, map.get(value) - 1);
        }
    }
    return arr;
}

console.log(intersection(arr1, arr2)); // [ 2, 4, 3, 5, 5 ]

数组和求下标

需求:给一个数组和一个数字,求数组中两个值的和等于这个数字的下标。

// 0.0.2/arraySumFindSub.js
const arr = [1, 2, 4, 8, 5];

const arraySum = (arr, target) => {
    const map = new Map();
    const newArr = [];
    for (let i = 0; i < arr.length; i++) {
        const value = arr[i];
        const difValue = target - value;
        if (map.has(difValue)) {
            newArr.push(map.get(difValue), i);
            break;
        }
        map.set(value, i)
    }
    return newArr;
}

console.log(arraySum(arr, 9)); // [0, 3]

本次代码 Github

你可以...