日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
20個(gè)實(shí)用的JavaScript代碼片段,助你成為更好的開(kāi)發(fā)者

開(kāi)發(fā)人員每天面臨的幾乎所有問(wèn)題都可以通過(guò)解決一組較小的問(wèn)題來(lái)解決,針對(duì)單個(gè)明確定義的問(wèn)題的小解決方案。這些解決方案可以最好地描述為“純函數(shù)”。

盡管這些函數(shù)中的大多數(shù)是在不同的庫(kù)中實(shí)現(xiàn)的,但重要的是要了解如何以及何時(shí)將困難的問(wèn)題分解為更小的問(wèn)題。這種解決問(wèn)題的思維方式將提高我們的開(kāi)發(fā)效率,并使我們成為更好的開(kāi)發(fā)人員。

今天的文章中,我分享的是我經(jīng)常用來(lái)解決各種問(wèn)題的 20 個(gè)有用的“純函數(shù)”的無(wú)序集合,希望對(duì)你也有用。

下面,我們開(kāi)始吧。

1、GetValue

給定一個(gè)對(duì)象或數(shù)組,函數(shù)將返回指定路徑的值,否則為 null。

const getValue = (obj, path) => path
.replace(/\[([^[\]]*)]/g, '.$1.')
.split('.')
.filter(prop => prop !== '')
.reduce((prev, next) => (
prev instanceof Object ? prev[next] : undefined
), obj);
getValue({ a: { b: c: 'd' } }, 'a.b.c'); // = d
getValue({ a: { b: c: [1, 2] } }, 'a.b.c[1]'); // = 2

2、Clamp

確保值在指定范圍內(nèi),否則“clamp”到最接近的最小值和最大值。

const clamp = (min, max, value) => {
if (min > max) throw new Error('min cannot be greater than max');
return value < min
? min
: value > max
? max
: value;
}
}
clamp(0, 10, -5); // = 0
clamp(0, 10, 20); // = 10

3、Sleep

在執(zhí)行下一個(gè)操作之前等待指定的持續(xù)時(shí)間(以毫秒為單位)。

const sleep = async (duration) => (
new Promise(resolve =>
setTimeout(resolve, duration)
)
);
await sleep(1000); // waits 1 sec

4、GroupBy

根據(jù)鍵控功能對(duì)對(duì)象中的相關(guān)項(xiàng)進(jìn)行分組和索引。

const groupBy = (fn, list) => (
list.reduce((prev, next) => ({
...prev,
[fn(next)]: [...(prev[fn(next)] || []), next]
}), {})
);
groupBy(vehicle => vehicle.make, [
{ make: 'tesla', model: '3' },
{ make: 'tesla', model: 'y' },
{ make: 'ford', model: 'mach-e' },
]);
// {
// tesla: [ { make: 'tesla', ... }, { make: 'tesla', ... } ],
// ford: [ { make: 'ford', ... } ],
// }

5、Collect By

根據(jù)鍵控功能創(chuàng)建包含相關(guān)項(xiàng)目的子列表。

import groupBy from './groupBy';
const collectBy = (fn, list) =>
Object.values(groupBy(fn, list));
collectBy(vehicle => vehicle.make, [
{ make: 'tesla', model: '3' },
{ make: 'tesla', model: 'y' },
{ make: 'ford', model: 'mach-e' },
]);
// [
// [ { make: 'tesla', ... }, { make: 'tesla', ... } ],
// [ { make: 'ford', ... } ],
// ]

6、Head

獲取列表的第一個(gè)元素。這個(gè)函數(shù)對(duì)于編寫(xiě)干凈易讀的代碼很有用。

const head = list => list[0];
head([1, 2, 3]); // = 1
head([]); // = undefined

7、Tail

獲取列表中除第一個(gè)元素之外的所有元素。這個(gè)函數(shù)對(duì)于編寫(xiě)干凈易讀的代碼很有用。

const tail = list => list.slice(1);
tail([1, 2, 3]); // = [2, 3]
tail([]); // = []

8、Flatten

通過(guò)遞歸地從嵌套子列表中提取所有項(xiàng)目來(lái)創(chuàng)建一個(gè)平面列表。

const flatten = list => list.reduce((prev, next) => ([
...prev,
...(Array.isArray(next) ? flatten(next) : [next])
]), []);
flatten([[1, 2, [3, 4], 5, [6, [7, 8]]]]); // = [1, 2, 3, 4, 5, 6, 7, 8]

9、Intersection By

查找鍵控函數(shù)定義的兩個(gè)列表中存在的所有值。

const intersectionBy = (fn, listA, listB) => {
const b = new Set(listB.map(fn);
return listA.filter(val => b.has(fn(val)));
};
intersectionBy(v => v, [1, 2, 3], [2, 3, 4]); // = [2, 3]
intersectionBy(v => v, [{ a: 1 }, { a: 2 }], [{ a: 2}, { a: 3 }, { a: 4 }]); // = [{ a: 2 }];

10、IndexBy

通過(guò)鍵控函數(shù)確定的值對(duì)列表中的每個(gè)元素進(jìn)行索引。

const indexBy = (fn, list) =>
list.reduce((prev, next) => ({
...prev,
[fn(next)]: next
}, {});
indexBy(val => val.a, [{ a: 1 }, { a: 2 }, { a: 3 }]);
// = { 1: { a: 1 }, 2: { a:2 }, 3: { a: 3 } }

11、DifferenceBy

查找第一個(gè)列表中不存在于第二個(gè)列表中的所有項(xiàng)目,由鍵控功能確定。

import indexBy from './indexBy';
const differenceBy = (fn, listA, listB) => {
const bIndex = indexBy(fn, listb);
return listA.filter(val => !bIndex[fn(val)]);
});
differenceBy(val => val, [1,2,3], [3,4,5]); // = [1,2]
differenceBy(
vehicle => vehicle.make,
[{ make: 'tesla' }, { make: 'ford' }, { make: 'gm' }],
[{ make: 'tesla' }, { make: 'bmw' }, { make: 'audi' }],
); // = [{ make: 'ford' }, { make: 'gm' }]

12、Recover With

如果給定函數(shù)拋出錯(cuò)誤,則返回默認(rèn)值。

const recoverWith = async (defaultValue, fn, ...args) => {
try {
const result = await fn(...args);
return result;
} catch (_e) {
return defaultValue;
}
}
recoverWith('A', val => val, 'B'); // = B
recoverWith('A', () => { throw new Error() }); // = 'A'

13、Distance

計(jì)算兩點(diǎn) p1 和 p2 之間的距離。

const distance = ([x0, y0], [x1, y1]) => (
Math.hypot(x1 - x0, y1 - y0)
);
distance([0, 1], [5, 4]); // = 5.8309518948453

14、Drop While

從列表中刪除元素,從第一個(gè)元素開(kāi)始,直到滿足 som 謂詞。

const dropWhile = (pred, list) => {
let index = 0;
list.every(elem => {
index++;
return pred(elem);
});
return list.slice(index-1);
}
dropWhile(val => (val < 5), [1,2,3,4,5,6,7]); // = [5,6,7]

15、Sum By

給定一些產(chǎn)生每個(gè)元素的單獨(dú)值的函數(shù),計(jì)算列表中所有元素的總和。

const sumBy = (fn, list) =>
list.reduce((prev, next) => prev + fn(next), 0);
sumBy(product => product.price, [
{ name: 'pizza', price: 10 },
{ name: 'pepsi', price: 5 },
{ name: 'salad', price: 5 },
]); // = 20

16、升序

給定一個(gè)評(píng)估函數(shù),創(chuàng)建一個(gè)升序比較器函數(shù)。

const ascending = (fn) => (a, b) => {
const valA = fn(a);
const valB = fn(b);
return valA < valB ? -1 : valA > valB ? 1 : 0;
}
const byPrice = ascending(val => val.price);
[{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
// = [{ price: 100 }, { price: 200 }, { price: 300 }]

17、降序

給定一個(gè)評(píng)估函數(shù),創(chuàng)建一個(gè)降序比較器函數(shù)。

const descending = (fn) => (a, b) => {
const valA = fn(b);
const valB = fn(a);
return valA < valB ? -1 : valA > valB ? 1 : 0;
}
const byPrice = descending(val => val.price);
[{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
// = [{ price: 300 }, { price: 200 }, { price: 100 }]

18、Find Key

在滿足給定predicate的索引中找到第一個(gè)鍵值。

const findKey = (predicate, index) => Object
.keys(index)
.find(key => predicate(index[key], key, index));
findKey(
car => !car.available,
{
tesla: { available: true },
ford: { available: false },
gm: { available: true }
},
); // = "ford"

19、Bifurcate By

將給定列表的值拆分為兩個(gè)列表,一個(gè)包含predicate函數(shù)評(píng)估為真值的值,另一個(gè)包含假值。

const bifurcateBy = (predicate, list) =>
list.reduce((acc, val, i) => (
acc[predicate(val, i) ? 0 : 1].push(val), acc),
[[], []]
);
bifurcateBy(val => val > 0, [-1, 2, -3, 4]);
// = [[2, 4], [-1, -3]]

20、Pipe

執(zhí)行從左到右的功能組合。所有額外的參數(shù)都將傳遞給列表中的第一個(gè)函數(shù),因此可以有任何數(shù)量。結(jié)果將在第二個(gè)傳遞,第二個(gè)的結(jié)果將傳遞給第三個(gè),……以此類推,直到處理完所有函數(shù)。

const pipe = (functions, ...args) => (
functions.reduce(
(prev, next) => Array.isArray(prev) ? next(...prev) : next(prev),
args
)
);
pipe([Math.abs, Math.floor, val => -val], 4.20); // = -4
pipe([(a, b) => a - b, Math.abs], 5, 10); // = 5

最后的想法

盡管所有這些功能對(duì)于幫助我們解決正在處理的問(wèn)題非常有用,但最重要的是,我們要知道如何將復(fù)雜困難的問(wèn)題進(jìn)行分解,這樣就可以獨(dú)立解決每個(gè)明確的小問(wèn)題。一旦你掌握了這個(gè)解決問(wèn)題的小技巧,那么你已經(jīng)在成為一名優(yōu)秀的開(kāi)發(fā)者的路上了!

如果你覺(jué)得我今天分享的內(nèi)容對(duì)你有所幫助,請(qǐng)點(diǎn)贊我,關(guān)注我,同時(shí),將這篇文章分享給你身邊做開(kāi)發(fā)的朋友,也許能夠幫助到他。

最后,感謝你的閱讀,祝編程愉快!


分享名稱:20個(gè)實(shí)用的JavaScript代碼片段,助你成為更好的開(kāi)發(fā)者
標(biāo)題網(wǎng)址:http://www.dlmjj.cn/article/cdcchsh.html