乐趣区

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

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

all

检查数组内是否所有元素都能通过函数 fn 的校验。

这个方法其实是在 Array.prototype.every() 的基础上提供了一个 Boolean 作为函数的默认值,在原有的基础上增加了检查是否包含假值的默认行为。

const all = (arr, fn = Boolean) => arr.every(fn);

// example
all([4, 2, 3], x => x > 1); // true
all([1, 2, 3]); // true
all([1, undefined]); // false

allEqual

检查数组内的所有元素是否都全等。

基于 Array.prototype.every() 的方法,通过校验所有元素与第一个元素是否都全等来校验数组内的所有元素是否都全等。其中使用了 === 这样的全等号,但是却没有检查到 NaN 这样的自不相等的元素。

const allEqual = arr => arr.every(val => val === arr[0]);

// example
allEqual([1, 2, 3]); // false
allEqual([1, 1, 1]); // true
allEqual([NaN, NaN]); // false

any

校验数组内是否有任意一个元素能通过函数 fn 的校验。

这个方法其实就是在 Array.prototype.some() 的基础上,提供了一个 Boolean 作为函数的默认值,在原有的基础上增加了检查是否包含真值的默认行为。

const any = (arr, fn = Boolean) => arr.some(fn);

// example
any([0, 1, 2, 0], x => x >= 2); // true
any([0, 0, 1, 0]); // true
any([0, 0, 0]); // false

arrayToCSV

将一个二维数组转换成 CSV(以逗号作为分隔符的字符串)。

使用 Array.prototype.map()Array.prototype.join() 方法将第二层数组转成符合规则的字符串,使用 Array.prototype.join('\n') 方法将第一层数组转换成 CSV 字符串,也就是换行。这其中使用 , 作为默认的分隔符。

const arrayToCSV = (arr, delimiter = ',') =>
    arr.map(v =>
        v.map(x =>
            (isNaN(x) ? `"${x.replace(/"/g, '""')}"` : x))
        .join(delimiter))
    .join('\n');

// own understand
const arrayToCSV = (arr, delimiter = ',') => {
    const arrNew = arr.map(vArr => {
        const vArrNew = vArr.map(val => {
            // 将一维数组转换成 CSV 字符串
            return isNaN(val) ? `"${val.replace(/"/g, '""')}"` : val;
        });
        return vArrNew.join(delimiter);
    });
    // 进行分行
    return arrNew.join('\n');
};

// example
arrayToCSV([['a', 'b'], ['c', 'd']]);
// ""a","b"
// "c","d""
arrayToCSV([['a', '"b" great'], ['c', 3.1415]]);
// ""a","""b"" great"//"c",3.1415"

bifurcate

给定一个包含 true/false 的数组,将一个数组进行指定的拆分,两个数组对比之后,相同索引的字段为 true 的拆分到第一个数组,其他的拆分到第二个数组。

使用了 Array.prototype.reduce() 循环需要拆分的数组,通过 Array.prototype.push() 将符合的规则的元素插入最后的结果数组中。

const bifurcate = (arr, filter) =>
    arr.reduce((acc, val, i) => (acc[filter[i] ? 0 : 1].push(val), acc), [[], []]);

// own understand
const bifurcate = (arr, filter) => {return arr.reduce((acc, val, i) => {acc[filter[i] ? 0 : 1].push(val);
        return acc;
    }, [[], []]);
};

// example
bifurcate(['beep', 'boop', 'foo', 'bar'], [true, true, false, true]); // [['beep', 'boop', 'bar'], ['foo'] ]

bifurcateBy

给定一个返回布尔值的函数,将一个数组拆分成两个数组,经函数处理后返回真值的在拆分后的第一个数组,返回假值的在第二个数组。

使用了 Array.prototype.reduce() 循环需要拆分的数组,通过 Array.prototype.push() 将符合的规则的元素插入最后的结果数组中。

const bifurcateBy = (arr, fn) =>
    arr.reduce((acc, val, i) => (acc[fn(val, i) ? 0 : 1].push(val), acc), [[], []]);

// own understand
const bifurcateBy = (arr, fn) => {return arr.reduce((acc, val, i) => {acc[fn[i] ? 0 : 1].push(val);
        return acc;
    }, [[], []]);
};

// example
bifurcateBy(['beep', 'boop', 'foo', 'bar'], x => x[0] === 'b'); // [['beep', 'boop', 'bar'], ['foo'] ]

chunk

将一个数组拆分成指定长度的小块,并将这些小块放到数组内。

使用 Array.from() 方法创建一个指定长度的稀疏数组,对这个稀疏数组进行循环赋值,每一次循环当中,根据计算的长度截取原数组作为当前循环的结果。

const chunk = (arr, size) =>
    Array.from({length: Math.ceil(arr.length / size) }, (v, i) =>
        arr.slice(i * size, i * size + size)
    );

// own understand
const chunk = (arr, size) => {
    // 创建一个稀疏数组
    return Array.from({length: Math.ceil(arr.length / size) }, (v, i) => {
        // 将原数组进行分块
        return arr.slice(i * size, i * size + size);
    });
};

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

compact

移除数组的所有假值。

使用 Array.prototype.filter() 过滤 JS 中的假值(false, null, 0, "", undefined, NaN)。

const compact = arr => arr.filter(Boolean);

// example
compact([0, 1, false, 2, '', 3,'a','e'* 23, NaN,'s', 34]); // [1, 2, 3,"a","s", 34]

countBy

给定一个函数将数组元素处理并进行分组,返回所有分组后的每个组的元素个数,返回对象的 key 为经过函数处理后分组的结果。

使用 Array.prototype.map() 对数组中的元素进行调用函数,返回的数组再使用 Array.prototype.reduce() 进行循环,最后的结果是一个对象,每一次循环都会在符合分组的 key 下进行计数。

const countBy = (arr, fn) =>
    arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => {acc[val] = (acc[val] || 0) + 1;
        return acc;
    }, {});

// own understand
const countBy = (arr, fn) => {const newArr = arr.map(typeof fn === 'function' ? fn : val => val[fn]);
    return newArr.reduce((acc, val) => {acc[val] = (acc[val] || 0) + 1;
        return acc;
    }, {});
};

// example
countBy([6.1, 4.2, 6.3], Math.floor); // {4: 1, 6: 2}
countBy(['one', 'two', 'three'], 'length'); // {3: 2, 5: 1}

countOccurrences

计算一个数组中指定元素出现的次数。

使用 Array.prototype.reduce() 方法循环数组,并且出现指定元素时对结果自增。

const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);

// own understand
const countOccurrences = (arr, val) => {return arr.reduce((a, v) => {if (v === val) {return a + 1;}
        return a;
    }, 0);
};

// example
countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
退出移动版