本周總結
這幾天在寫Echarts自定義需求的時候發現了,圖形化算法和函數式編程的應用場景,很多時候我們現在學的東西並一定在當前的這種狀態有用,但是興趣吧,喜歡就去學唄,沒准在日后的工作日常中用到了
我喜歡這種既學習到東西還能隨便給我發發工資的生活
熱情只有在某個年齡段才會有的,所以把握現在,失去熱情就等於失去了生活的樂趣
以前我寫過幾遍關於reduce
的文章,但是可能沒有連貫性或者說沒有單一,就在前幾天在解決Echarts自定義需求的時候,終於發現了結合的用武之地了
隨便把filter也介紹下,畢竟我也用的少
reduce 特性
[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'
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), {},
));
數組扁平化
連接兩個數組用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));
// 細節
&& 做判斷
遞歸注意是把改變后的值作為參數再次傳入函數
查找某個數在數組的位置
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]]
filter
取出自身數組不重復的數
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));
##############################################################################################.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................