30-seconds-of-code-Array-学习六

53次阅读

共计 5321 个字符,预计需要花费 14 分钟才能阅读完成。

原始地址:https://github.com/30-seconds…

permutations

生成数组元素的所有排列组成的数组(包含重复项)。

对于数组长度为 2 的数组直接返回结果,对于长度小于 2 的数组直接返回原数组。对于其他长度的数组,首先使用 Array.prototype.reduce() 对数组中的元素进行循环,在每一个循环中,使用 Array.prototype.slice() 剔除本次循环的值,,并对剩余的元素数组递归使用当前方法,最后使用 Array.prototype.map() 将结果数组拼接起来。

const permutations = arr => {if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr;
    return arr.reduce((acc, item, i) =>
            acc.concat(permutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map(val => [item, ...val])
            ),
        []);
};

// example
permutations([1, 33, 5]); // [[ 1, 33, 5], [1, 5, 33], [33, 1, 5], [33, 5, 1], [5, 1, 33], [5, 33, 1] ]

pull

将给定数组中的指定值移除。

通过 Array.isArray() 校验给定参数是否是数组,非数组的时候将后续所有参数转成参数数组。使用 Array.prototype.filter()Array.prototype.includes() 获取出留存的元素数组,然后使用 Array.prototype.length = 0 将原数组设置为空数组,再将留存的元素使用 Array.prototype.push() 填充到原数组中。

const pull = (arr, ...args) => {let argState = Array.isArray(args[0]) ? args[0] : args;
    let pulled = arr.filter((v, i) => !argState.includes(v));
    arr.length = 0;
    pulled.forEach(v => arr.push(v));
};

// example
let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
pull(myArray, 'a', 'c'); // myArray = ['b', 'b']

pullAtIndex

更改给定的数组过滤掉指定索引的值,返回被移除的值的数组,改变原来的数组。

使用 Array.prototype.includes() 获取出被移除的元素组成的数组,然后再使用 Array.prototype.filter() 过滤掉被移除的元素,将原数组的长度设置为 0 后成为一个空数组,再将留存的元素使用 Array.prototype.push() 填充到原数组内,最后返回被移除的元素数组。

const pullAtIndex = (arr, pullArr) => {let removed = [];
    let pulled = arr
        .map((v, i) => (pullArr.includes(i) ? removed.push(v) : v))
        .filter((v, i) => !pullArr.includes(i));
    arr.length = 0;
    pulled.forEach(v => arr.push(v));
    return removed;
};

// own understand

const pullAtIndex = (arr, pullArr) => {const removed = [];
    const left = [];
    for (let i = 0; i < arr.length; i++) {if (pullArr.includes(i)) {removed.push(arr[i]);
        } else {left.push(arr[i]);
        }
    }
    arr.length = 0;
    left.forEach(item => arr.push(item));
    return removed;
};

// example
let myArray = ['a', 'b', 'c', 'd'];
let pulled = pullAtIndex(myArray, [1, 3]); // myArray = ['a', 'c'] , pulled = ['b', 'd']

pullAtValue

更改给定的数组过滤掉指定的值,返回被移除的值的数组,改变原来的数组。

使用 Array.prototype.filter()Array.prototype.includes() 获取最后存留的元素,使用 Array.prototype.length = 0 可以直接将数组设置为空数组,然后循环存留的元素数组并将其中的值使用 Array.prototype.push() 填充到原数组中,返回最后被删除的元素。

const pullAtValue = (arr, pullArr) => {let removed = [],
        pushToRemove = arr.forEach((v, i) => (pullArr.includes(v) ? removed.push(v) : v)),
        mutateTo = arr.filter((v, i) => !pullArr.includes(v));
    arr.length = 0;
    mutateTo.forEach(v => arr.push(v));
    return removed;
};

// own understand
const pullAtValue = (arr, pullArr) => {const removed = [];
    for (let i = 0; i < arr.length; i++) {if (pullArr.includes(arr[i])) {removed.push(arr[i]);
            arr.splice(i--, 1);
        }
    }
    return removed;
};

// example
let myArray = ['a', 'b', 'c', 'd'];
let pulled = pullAtValue(myArray, ['b', 'd']); // myArray = ['a', 'c'] , pulled = ['b', 'd']

pullBy

根据给定的迭代器函数,将数组中符合要求的元素过滤掉,改变原来的数组。

首先需要检查给定的最后一个参数是否是一个函数。使用 Array.prototype.map() 对给定的参数数组应用迭代器函数,然后使用 Array.prototype.filter()Array.prototype.includes() 过滤掉不符合要求的数组,然后将给定的参数数组的长度设置为 0,最后使用 Array.prototype.push() 将结果放到参数数组内。

const pullBy = (arr, ...args) => {
    const length = args.length;
    let fn = length > 1 ? args[length - 1] : undefined;
    fn = typeof fn == 'function' ? (args.pop(), fn) : undefined;
    let argState = (Array.isArray(args[0]) ? args[0] : args).map(val => fn(val));
    let pulled = arr.filter((v, i) => !argState.includes(fn(v)));
    arr.length = 0;
    pulled.forEach(v => arr.push(v));
};

// example
var myArray = [{x: 1}, {x: 2}, {x: 3}, {x: 1}];
pullBy(myArray, [{ x: 1}, {x: 3}], o => o.x); // myArray = [{x: 2}]

reducedFilter

对给定的对象数组应用指定的过滤函数后,返回结果数组中指定的字段。

首先使用 Array.prototype.filter() 对过滤掉给定数组中不符合要求的元素,对剩余的元素数组使用 Array.prototype.map() 进行循环,再循环中使用 Array.prototype.reduce() 对给定的 keys 数组进行循环,从结果数组中取出符合要求的对象作为结果集。

const reducedFilter = (data, keys, fn) =>
    data.filter(fn).map(el =>
        keys.reduce((acc, key) => {acc[key] = el[key];
            return acc;
        }, {})
    );

// own understand
const reducedFilter = (data, keys, fn) => {const arrFilter = data.filter(fn);
    const resultList = [];
    for (const item of arrFilter) {const result = {};

       for (const key of keys) {result[key] = item[key];
        }
        resultList.push(result);
    }
    return resultList;
};

// example
const data = [
    {
        id: 1,
        name: 'john',
        age: 24
    },
    {
        id: 2,
        name: 'mike',
        age: 50
    }
];

reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{id: 2, name: 'mike'}]

reduceSuccessive

对一个数组中得值循环应用给定得累加器函数,返回应用后的结果数组。

const reduceSuccessive = (arr, fn, acc) =>
    arr.reduce((res, val, i, arr) => (res.push(fn(res.slice(-1)[0], val, i, arr)), res), [acc]);

// example
reduceSuccessive([1, 2, 3, 4, 5, 6], (acc, val) => acc + val, 0); // [0, 1, 3, 6, 10, 15, 21]

reduceWhich

给数组中的元素应用给定比较器函数后,返回数组的最大值 / 最小值,默认取最小值。

使用 Array.prototype.reduce() 对数组进行循环,比较数组前后两个元素,默认取比较小的值。

const reduceWhich = (arr, comparator = (a, b) => a - b) =>
    arr.reduce((a, b) => (comparator(a, b) >= 0 ? b : a));

// example
reduceWhich([1, 3, 2]); // 1
reduceWhich([1, 3, 2], (a, b) => b - a); // 3
reduceWhich([{ name: 'Tom', age: 12}, {name: 'Jack', age: 18}, {name: 'Lucy', age: 9}],
    (a, b) => a.age - b.age
); // {name: "Lucy", age: 9}

reject

返回给定数组中无法通过给定校验函数的所有元素组成的数组。

const reject = (pred, array) => array.filter((...args) => !pred(...args));

// example
reject(x => x % 2 === 0, [1, 2, 3, 4, 5]); // [1, 3, 5]
reject(word => word.length > 4, ['Apple', 'Pear', 'Kiwi', 'Banana']); // ['Pear', 'Kiwi']

remove

移除数组中通过指定校验函数的元素,返回被移除的元素组成的数组,原数组只剩余不能通过指定校验函数的元素。

使用 Array.isArray() 校验给定的参数是否是数组,非数组的时候直接返回空数组,然后使用 Array.prototype.filter() 过滤出只符合要求的元素数组,使用 Array.prototype.reduce() 得到的新数组进行循环,在循环中将符合要求的元素通过 Array.prototype.splice() 从给的数组中移除掉,并将这个元素返回。

const remove = (arr, func) =>
    Array.isArray(arr)
        ? arr.filter(func).reduce((acc, val) => {arr.splice(arr.indexOf(val), 1);
                return acc.concat(val);
            }, [])
        : [];

// own understand
const remove = (arr, func) => {if (!Array.isArray(arr)) {return [];
    }
    // 获取需要保留的元素
    const newArr = arr.filter(func);
    return newArr.reduce((acc, val) => {arr.splice(arr.indexOf(val), 1);
        return acc.concat(val);
    }, []);
};

// example
remove([1, 2, 3, 4], n => n % 2 === 0); // [2, 4]

正文完
 0