这几天在写Echarts自定义需求的时候发现了,图形化算法和函数式编程的应用场景,不少时候咱们如今学的东西并必定在当前的这种状态有用,可是兴趣吧,喜欢就去学呗,没准在往后的工做平常中用到了算法
我喜欢这种既学习到东西还能随便给我发发工资的生活编程
热情只有在某个年龄段才会有的,因此把握如今,失去热情就等于失去了生活的乐趣数组
之前我写过几遍关于reduce
的文章,可是可能没有连贯性或者说没有单一,就在前几天在解决Echarts自定义需求的时候,终于发现告终合的用武之地了app
随便把filter也介绍下,毕竟我也用的少函数式编程
[1,2,3,4,4].reduce((acc,val)=> //第一种 acc.concat(xxx),[] //第二种 (acc.push(xxx),acc),[] //第三种 单个值 acc+xxx,0 //第四种,若是是字符串 acc+xxx,'' //第五种,对象 acc[val]=xxx,{} ) 最普通的格式 [xxx].reduce((acc,val)=>{ 操做 return acc },[]) 第一个参数是函数,第二个参数是格式,0/{},[],'' 注意当使用concat应该直接return [1,2,3,4,[1,2,3]].reduce((acc,val)=>{ return acc.concat(val) },[])
['beep', 'boop', 'foo', 'bar'], [true, true, false, true]
函数
//简单的例子 let arr1 = [1, 2, 3, 4, 5]; let arr2 = [1, 0, 1, 0, 1]; 第一种方法 let arr3 = []; for (let i in arr2) { if (arr2[i]) { arr3.push(arr1[i]) } } console.log(arr3); 第二种方法 arr1.reduce((acc, item, index) => ( arr2[index] && acc.push(item), acc) , []); 观察特色 (acc,val,i)=>(操做,acc) 最后返回的是acc [] Array.from({length:0}) [[],[]] 有没有想过用 Array.from来实现 Array.from({length:2}).map(v=>[]) 咱们能够知道 length的值不多是死的 若是二维的数组能够是 length:Math.max(...arr.map(x=>x.length))
删选出数组中每一个数首字母是否含有'b'oop
let arr = ['beep', 'boop', 'foo', 'bar']; console.log(arr.reduce((acc, val) => (val[0] === 'b' && acc.push(val), acc), [])); 进阶 每一个数是否含有'b' arr.reduce((acc, val) => (val.indexOf('b') >-1 && acc.push(val), acc), [])
计算次数学习
计算一个数组中某值的次数 [1, 2, 3, 4, 1, 1, 1, 1, 2, 3, 4].reduce( (acc, val) => val === 1? acc + 1 : acc, 0, ) 细节解读 0表明从0开始,acc是迭代的值,默认为0 console.log(['one', 'two', 'three','one', 'two', 'three'].reduce((acc, val) => (acc[val] = (acc[val] || 0) + 1, acc), {}, )); 细节解读 (acc[val] = (acc[val] || 0) + 1 第一次进入的时候 acc[val] 确定是不存在的因此默认给0,后面给值了就叠加了 升级理解 计算长度的次数 console.log(['one', 'two', 'three', 'one', 'two', 'three'].map(v => v.length).reduce( (acc, val) => (acc[val] = (acc[val] || 0) + 1, acc), {}, ));
数组扁平化this
链接两个数组用concat方法 [1, 2, 3, 4, 5, [1, 3, 4], 5].reduce((acc, val) => acc.concat(val),[] ); const flatter=(arr,depth=1)=> arr.reduce((acc,val)=> acc.concat(depth>1&&Array.isArray(val)?flatter(val,depth-1):val),[] ); console.log(flatter([1,[2,3,4,[2,3,4,[1,2,3]]]],3)); // 细节 && 作判断 递归注意是把改变后的值做为参数再次传入函数
查找某个数在数组的位置code
let arr = [1, 2, 3, 4, 1, 2, 1, 3, 1]; arr.reduce((acc, val, i) => (val === 2 && acc.push(i), acc), [], );
字符串操做
需求在数组的偶数项或者奇数项插入特定的字符 ['pen', 'pineapple', 'apple', 'pen'].reduce( (acc, val, i) => i % 2 === 0 ? acc + val + '我' : acc + val + '你' , '', ); //pen我pineapple你apple我pen你
返回数组每一项中最长的那项
['this', 'is', 'a', 'testcase'].reduce( (acc, val) => (acc.length > val.length ? acc : val), 0, ) // 求和 [1,2,3,4,5].reduce( (acc,val)=>acc+val,0 )
把两个数组合并成一个对象
let arr1 = [1, 2, 3]; let arr2 = arr1.map(v => v * 3); arr1.reduce((acc, val, i) => (acc[val] = arr2[i], acc), {}, ); // { '1': 3, '2': 6, '3': 9 }
reduce里面嵌套高阶函数
能够对数组中的多个对象进行分组
const partition = (arr, fn) => arr.reduce( (acc, val, i, arr) => { acc[fn(val, i, arr) ? 0 : 1].push(val); return acc; }, [[], []] ); const users = [{ user: 'barney', age: 36, active: false }, { user: 'fred', age: 40, active: true }]; partition(users, o => o.active); // [[{ 'user': 'fred', 'age': 40, 'active': true }],[{ 'user': 'barney', 'age': 36, 'active': false }]] 用普通函数定义变量 arr.reduce((acc, val) => { let a = val.age; acc[a ? 0 : 1].push(val); return acc },[[],[]]);
复杂的数组交换位置 (底层逻辑暂时不懂,先留着等技术提升了再来解决)
[1,2,3] => 每两个数之间交换位置,递归,遍历 首先判断当数组是两个数,两个数之间交换位置 const permutations = arr => { if (arr.length <= 2) return arr.length === 2 ? [arr, [arr[1], arr[0]]] : arr; return arr.reduce( (acc, val, i) => { //就是这块合并,分解,再遍历 return acc.concat( permutations([...arr.slice(0, i), ...arr.slice(i + 1)]) .map(item => [val, ...item]), ); }, [], ); }; console.log(permutations([1, 2, 3, 4]));
对数组进行对象删选再进行属性删选
const data = [ { id: 1, name: 'john', age: 24 }, { id: 2, name: 'mike', age: 50 } ]; let obj = ['id', 'name']; data.filter(v=>v.age>24) .map(item=> obj.reduce((acc,val)=>(acc[val]=item[val],acc),{}))
reduce 实现排序
// 升序 [0,1,2,3].reduce((acc,val)=>acc-val>=0?acc:val); //降序 [0,1,2,3].reduce((acc,val)=>val-acc>=0?acc:val);
reduce对数组的对象属性进行去重
let arr = [ {id: 0, value: 'a'}, {id: 1, value: 'b'}, {id: 2, value: 'c'}, {id: 1, value: 'd'}, {id: 0, value: 'e'}, ]; fn=(a,b)=>a.value===b.value; console.log(arr.reduce((acc, val) => { if (!acc.some(x => fn(val, x))) acc.push(val); return acc }, [])); //[ { id: 0, value: 'a' }, // { id: 1, value: 'b' }, // { id: 2, value: 'c' }, // { id: 1, value: 'd' }, // { id: 0, value: 'e' } ]
多个数组的每项进行拆成独立的数组
const unzip = arr => arr.reduce( (acc, val) => (val.forEach((v, i) => acc[i].push(v)), acc), Array.from({ length: Math.max(...arr.map(x => x.length)) }).map(x => []) ); unzip([['a', 1, true], ['b', 2, false]]); // [['a', 'b'], [1, 2], [true, false]]
取出自身数组不重复的数
let arr=[1,3,3,4,4,5,6]; arr.filter((v,i,array)=>array.indexOf(v)==array.lastIndexOf(v)) let arr = [1, 2, 3, 1, 2, 5]; const fn = (a, b) => a === b; console.log(arr.filter((v, i) => arr.every((w, j) => (j === i) === fn(w, v))));
filter筛选出相同或者不一样的数
//第一种方式 let arr1 = [1, 2, 3, 4, 5]; let arr2 = [1, 0, 1, 0, 1]; console.log(arr1.filter(v => !arr2.includes(v))); //第二种形式 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] //第三种形式 a中不存在b中的数 let arr1 = [1, 3, 4, 5, 6, 7,6,6,7,7,20]; let arr2 = [3, 4, 5, 8, 9, 20, 12]; console.log(arr1.filter(v => arr2.findIndex(w => w === v) === -1)); 若是是小数能够先进行处理再比较 let arr1 = [1, 1.2, 1.5, 3, 0]; let arr2 = [1.9, 3, 0, 3.9]; console.log(arr1.filter(v => arr2.findIndex(w => Math.round(w)=== Math.round(v)) === -1));
.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................