数组的高级用法 (3)

120 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

上篇,我们一起学些了数组去重和求交集,今天我们继续数组的奇妙之旅。

大家,动起来。

差集

非常主流的的Set配合数组includes去重。

const arr1 = [0, 1, 2, 4] 
const arr2 = [3, 2, 0] 
const values = [...new Set(arr1)].filter(item => !arr2 .includes(item)) 
console.log(values)  // [0, 2]

非常类似上篇的交集,直接贴代码

// 引用类型
function difference(arr1, arr2, key){ 
    const map = new Map();
    arr1.forEach(val=> map.set(val[key]))

    return arr2.filter(val=> {
        return !map.has(val[key]);
    });
}


// 原始数据类型
function differenceBase(arr1, arr2){ 
    const map = new Map();
    arr1.forEach(val=> map.set(val))

    return arr2.filter(val=> {
        return !map.has(val);
    });
}

求和

接下来将的是我个人原称其最强的方法Array.prototype.reduce就相当的遍历。

先看看很流行的例子:

var arr = [3,2,1,6];

const result = arr.reduce((total,cur)=> total + cur, 0) //  12

假如不是这种原始类型的数据呢?

var products = [{price:15, count:1}, {price:25, count:2}, {price:8, count:2}];

const result = products.reduce((total,cur)=> {
    return total + cur.price * cur.count
}, 0) 

// 81

queryString

queryString常用的方法要么是正则,要么是遍历,其中Array.prototype.reduce就相当的遍历。

 function getQueryString(){
     return location.search.slice(1)
        .split("&")
        .filter(Boolean)
        .reduce(function(obj, cur){
            var arr = cur.split("=");
            if(arr.length !=2){
                return obj;
            }
            obj[decodeURIComponent(arr[0])] = decodeURIComponent(arr[1]);
            return obj;               
        }, {})
 }
 
 // https://juejin.cn/post/6844904194919366669?q=1&sdkhaksd=666
 getQueryString() // {q: '1', sdkhaksd: '666'}

核心就是Array.prototype.reduce + Array.prototype.filter

compose

就是让一个函数的结果作为另外一个函数的参数继续执行。

我们直接使用redux的代码:

 function compose(...funcs) {
  if (funcs.length === 0) {
    // infer the argument type so it is usable in inference down the line
    return (arg) => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  return funcs.reduce(
    (a, b) =>
      (...args) =>
        a(b(...args))
  )
}

测试代码:

function double(x){
    return x*2
}

function square(x){
    return x*x
}

compose(double,square)(6)  // 72
//  (6*6)*2 = 36 *2 = 72

如果像从前往后执行,把reduce换成 reduceRight

 function compose(...funcs) {
  if (funcs.length === 0) {
    // infer the argument type so it is usable in inference down the line
    return (arg) => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  return funcs.reduceRight(
    (a, b) =>
      (...args) =>
        a(b(...args))
  )
}

测试代码:

function double(x){
    return x*2
}

function square(x){
    return x*x
}

compose(double,square)(6)  // 144
//  (6*2)*(6*2) = 12 * 12 = 144

Promise顺序执行

这里直接用云的世界 的代码了:

function runPromises(promiseCreators, initData) {
    return promiseCreators
        .reduce((promise, next) => promise
                .then((data) => next(data))
            , Promise.resolve(initData));
}

示例代码:

var promise1 = function (data = 0) {
    return new Promise(resolve => {
        resolve(data + 1000);
    });
}
var promise2 = function (data) {
    return new Promise(resolve => {
        resolve(data -500);
    });
}

runPromises([promise1, promise2], 1).then(res=>console.log(res)); 

//1 + 1000 - 500 = 1001 - 500 = 501

小结

今天学习了数组获取queryString, compose函数, Promise的顺序执行。 今天你收获了吗? 请期待下一章节吧!

引用

【干货】私藏的这些高级工具函数,你拥有几个