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

42次阅读

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

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

initialize2DArray

初始化一个给定高、宽的二维数组,并且填充给定值。

首先创建一个给定高度的稀疏数组,然后对这个稀疏数组使用 Array.prototype.map() 方法,在稀疏数组中每个元素位置上创建一个给定宽度的稀疏数组,并使用 Array.prototype.fill() 填充给定的值。

const initialize2DArray = (w, h, val = null) =>
    Array.from({length: h}).map(() => Array.from({ length: w}).fill(val));

// own understand
const initialize2DArray = (w, h, val = null) => {const newArr = Array.from({ length: h});
    return newArr.map(() => Array.from({ length: w}).fill(val));
};

// example
initialize2DArray(2, 2, 0); // [[0,0], [0,0]]

initializeArrayWithRange

初始化一个指定起始值和结束值的数组,并在数组中填充符合给定间隔值的数组。

首先使用 Array.from() 创建一个符合长度要求的稀疏数组,创建的过程中对每一个位置应用一个赋值方法,让最后的结果达到预期要求。

const initializeArrayWithRange = (end, start = 0, step = 1) =>
    Array.from({length: Math.ceil((end - start + 1) / step) }, (v, i) => i * step + start);

// own understand
const initializeArrayWithRange = (end, start = 0, step = 1) => {
    // 创建一个符合长度要求的数组
    const arr = Array.from({length: Math.ceil((end - start + 1) / step) });
    // 对数组每一个索引进行填充
    return arr.map((v, i) => i * step + start);
};

// example
initializeArrayWithRange(5); // [0,1,2,3,4,5]
initializeArrayWithRange(7, 3); // [3,4,5,6,7]
initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]

initializeArrayWithRangeRight

初始化一个指定起始值和结束值的数组,初始化过程为从右到左创建,并在数组中填充符合给定间隔值的数组。

首先使用 Array.from() 创建一个符合长度要求的稀疏数组,对这个稀疏数组使用 Array.prototype.map() 方法对每一个索引以用赋值的方法,赋值的方法中主要是找出当前从左索引所对应的从右索引,然后对指定位置赋值。

const initializeArrayWithRangeRight = (end, start = 0, step = 1) =>
    Array.from({length: Math.ceil((end + 1 - start) / step) }).map((v, i, arr) => (arr.length - i - 1) * step + start
    );

// own understand
const initializeArrayWithRangeRight = (end, start = 0, step = 1) => {const arr = Array.from({ length: Math.ceil((end + 1 - start) / step) });
    return arr.map((v, i, newArr) => {
        const rightIndex = arr.length - i - 1;
        return rightIndex * step + start;
    });
};

// example
initializeArrayWithRangeRight(5); // [5,4,3,2,1,0]
initializeArrayWithRangeRight(7, 3); // [7,6,5,4,3]
initializeArrayWithRangeRight(9, 0, 2); // [8,6,4,2,0]

initializeArrayWithValues

初始化一个填充了指定长度的指定值的数组。

首先使用了 Array 的构造方法初始化了一个指定长度的稀疏数组,然后使用 Array.prototype.fill() 对数组填充指定的值。

const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);

// example
initializeArrayWithValues(5, 2); // [2, 2, 2, 2, 2]

initializeNDArray

创建一个给定值的 n 维数组。

给定一个初始值,后面的参数个数表示维数,参数的值表示当前维的高度。

const initializeNDArray = (val, ...args) =>
    args.length === 0
        ? val
        : Array.from({length: args[0] }).map(() => initializeNDArray(val, ...args.slice(1)));

// own understand
const initializeNDArray = (val, ...args) => {if (args.length === 0) {return val;}
    // 创建一个稀疏数组,只包含长度
    const newArr = Array.from({length: args[0] });
    return newArr.map(() => {
        // 减少一维
        return initializeNDArray(val, ...args.slice(1));
    });
};

// example
initializeNDArray(1, 3); // [1,1,1]
initializeNDArray(5, 2, 2, 2); // [[[5,5],[5,5]],[[5,5],[5,5]]]

intersection

对两个数组进行取交集。

对数组使用 Set 的构造函数称为一个 Set 对象,这样可以提高查询的效率。

const intersection = (a, b) => {const s = new Set(b);
    return a.filter(x => s.has(x));
};

intersection([1, 2, 3], [4, 3, 2]); // [2, 3]

intersectionBy

对两个数组应用同样的的函数后,返回第一个数组中符合要求的值的数组(交集)。

首先使用 Array.prototype.map() 对第二个数组应用指定函数,然后使用 Array.prototype.filter() 过滤掉第一个数组中不符合要求的元素,最后返回第一个数组中符合要求的数组。

const intersectionBy = (a, b, fn) => {const s = new Set(b.map(fn));
    return a.filter(x => s.has(fn(x)));
};

// example
intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); // [2.1]

intersectionWith

通过比较器函数对两个数组的元素进行比较,返回第一个数组中符合要求的值的数组(交集)。

先使用 Array.prototype.findIndex() 校验第二个数组中是否有和第一个数组元素中符合比较器函数的元素,没有的话就是用 Array.prototype.filter() 对第一个数组进行过滤,只剩下符合要求的元素。

const intersectionWith = (a, b, comp) => a.filter(x => b.findIndex(y => comp(x, y)) !== -1);

// example
intersectionWith([1, 1.2, 1.5, 3, 0], [1.9, 3, 0, 3.9], (a, b) => Math.round(a) === Math.round(b)); // [1.5, 3, 0]

isSorted

返回数组元素的排序情况:升序(1),降序(-1),无序(0)。

const isSorted = arr => {let direction = -(arr[0] - arr[1]);
    for (let [i, val] of arr.entries()) {direction = !direction ? -(arr[i - 1] - arr[i]) : direction;
        if (i === arr.length - 1) return !direction ? 0 : direction;
        else if ((val - arr[i + 1]) * direction > 0) return 0;
    }
};

// own understand
const isSorted = arr => {
    // 第一个和第二个排序情况
    let direction = -(arr[0] - arr[1]);
    for (const [index, value] of arr.entries()) {
        // 只要有顺序的时候就要继续比较,为 0 的时候不需要比较
        direction = !direction ? -(arr[i - 1] - arr[i]) : direction;
        if (index === arr.length - 1) {
            // 最后一个元素的时候返回排序情况
            return !direction ? 0 : direction;
        } else if ((value - arr[index + 1]) * direction > 0) {
            // 要么升序要么降序,顺序改变就直接返回无序的结果
            return 0;
        }
    }
};

// example
isSorted([0, 1, 2, 2]); // 1
isSorted([4, 3, 2]); // -1
isSorted([4, 3, 5]); // 0

join

将数组中的所有元素连接成一个字符串并返回该字符串,指定一个分隔符和结束分隔符。

使用 Array.prototype.reduce() 对数组进行循环,提供了两个分隔符,第一个默认为 , 使用在除最后两个元素之间的其他元素之间,第二个默认与第一个分隔符相同,使用在最后两个元素之间。对元素的拼接分成了三种情况校验。

const join = (arr, separator = ',', end = separator) =>
    arr.reduce((acc, val, i) =>
        i === arr.length - 2
            ? acc + val + end
            : i === arr.length - 1
            ? acc + val
            : acc + val + separator,
        ''
    );

// own understand
const join = (arr, separator = '', end = separator) => {return arr.reduce((acc, val, i) => {if (i === arr.length - 2) {
            // 倒数第二个
            return acc + val + end;
        } else if (i === arr.length - 1) {
            // 倒数第一个
            return acc + val;
        } else {
            // 正常其他元素
            return acc + val + separator;
        }
    }, '');
};

// example
join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); // "pen,pineapple,apple&pen"
join(['pen', 'pineapple', 'apple', 'pen'], ','); // "pen,pineapple,apple,pen"
join(['pen', 'pineapple', 'apple', 'pen']); // "pen,pineapple,apple,pen"

正文完
 0