🔍 搜尋結果:typescript'

🔍 搜尋結果:typescript'

Array.reduce() 已被山羊化 🐐✨

標題說明了一切🐐。我想談談我一直以來最喜歡的 JavaScript 陣列方法: **Array.reduce()** 。我知道有很多競爭者,但請聽我說完。 reduce() 不只是一個方法;這是一種生活方式✨。 我不想撒謊,當我第一次開始並發現reduce 時,它有點令人生畏。我花了一段時間才在程式碼中自信地使用它。但當我這麼做的時候,遊戲規則就改變了。突然間,我可以輕鬆地對陣列執行複雜的操作,將它們轉換為我需要的任何內容。我的程式碼變得更快更乾淨。 但不要只相信我的話。讓我向您展示使用reduce() 可以實現的一些功能。是時候深入研究 Array.reduce() 並發現為什麼它絕對是山羊了! 🐐 Array.reduce() 的 9 個用例 🐐 ------------------------ ### 用例 1:對數字求和 reduce() 最直接的用例之一是對一堆數字求和。假設您有一個整數陣列,並且您想要找到總和。 ``` const numbers: number[] = [1, 2, 3, 4, 5]; const sum: number = numbers.reduce((acc, curr) => acc + curr, 0); console.log(sum); // Output: 15 ``` 繁榮!只需一行程式碼,您就可以計算出陣列中所有元素的總和。累加器的初始值設為 0,並且在每次迭代中,我們將當前元素新增至累加器。 \*\* 獎勵:如果您選擇忽略起始值,reduce 將只使用陣列中的第一項。不過我傾向於總是包含一個初始值,這樣比較容易閱讀。 ### 用例 2:展平陣列 您是否曾經發現自己有一個陣列陣列並想:“我希望我可以將其扁平化為一個陣列”? ``` const nestedArray: number[][] = [[1, 2], [3, 4], [5, 6]]; const flattenedArray: number[] = nestedArray.reduce((acc, curr) => acc.concat(curr), []); console.log(flattenedArray); // Output: [1, 2, 3, 4, 5, 6] ``` 在此範例中,我們從一個空陣列開始作為初始累加器值。然後,在每次迭代中,我們使用 concat() 方法將目前子陣列連接到累加器。最後,我們就有了一個完美的扁平化陣列。 我知道您也可以使用`Array.flat()`來做到這一點。然而,了解如何使用reduce 很重要,以防您想對每個專案執行額外的操作。 ### 用例 3:對物件進行分組 假設您有一個物件陣列,並且您希望根據特定屬性對它們進行分組。 reduce() 是完成這項工作的完美工具。 ``` interface Person { name: string; age: number; } const people: Person[] = [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }, { name: 'Charlie', age: 25 }, { name: 'Dave', age: 30 } ]; const groupedByAge: { [key: number]: Person[] } = people.reduce((acc, curr) => { if (!acc[curr.age]) { acc[curr.age] = []; } acc[curr.age].push(curr); return acc; }, {}); console.log(groupedByAge); /* Output: { '25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], '30': [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }] } */ ``` 在本例中,我們使用一個物件作為初始累加器值。我們檢查累加器是否已經具有當前年齡的屬性。如果沒有,我們為該年齡建立一個空陣列。然後,我們將目前物件推入對應的年齡陣列中。最後,我們得到一個物件,其中鍵是年齡,值是該年齡的人的陣列。 現在您也可以使用更新的`groupBy`方法,但是,理解這個久經考驗的真正經典方法很重要。 ### 用例 4:建立查找圖 我個人最喜歡的是使用reduce()從陣列建立查找映射。在效能和程式碼可讀性方面,它改變了遊戲規則。停止使用那些緩慢的 find() 或 filter() 呼叫。 ``` interface Product { id: number; name: string; price: number; } const products: Product[] = [ { id: 1, name: 'Laptop', price: 999 }, { id: 2, name: 'Phone', price: 699 }, { id: 3, name: 'Tablet', price: 499 }, ]; const productMap: { [key: number]: Product } = products.reduce((acc, curr) => { acc[curr.id] = curr; return acc; }, {}); console.log(productMap); /* Output: { '1': { id: 1, name: 'Laptop', price: 999 }, '2': { id: 2, name: 'Phone', price: 699 }, '3': { id: 3, name: 'Tablet', price: 499 } } */ // Accessing a product by ID const laptop: Product = productMap[1]; console.log(laptop); // Output: { id: 1, name: 'Laptop', price: 999 } ``` 透過使用reduce()建立查找映射,您可以以恆定的時間複雜度透過元素的唯一辨識碼來存取元素。不再需要循環遍歷陣列來尋找特定專案。 ### 用例 5:計算出現次數 曾經需要計算陣列中元素的出現次數嗎? reduce() 已經幫你解決了。 ``` const fruits: string[] = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']; const fruitCounts: { [key: string]: number } = fruits.reduce((acc, curr) => { acc[curr] = (acc[curr] || 0) + 1; return acc; }, {}); console.log(fruitCounts); /* Output: { 'apple': 3, 'banana': 2, 'orange': 1 } */ ``` 在這個例子中,我們初始化一個空物件作為累加器。對於陣列中的每個水果,我們檢查它是否已作為累加器物件中的屬性存在。如果是,我們將其計數加 1;否則,我們將其初始化為 1。 ### 用例 6:組合函數 函數式程式設計愛好者一定會喜歡這個。 reduce() 是一個強大的函陣列合工具。您可以使用它來建立逐步轉換資料的函數管道。 ``` const add5 = (x: number): number => x + 5; const multiply3 = (x: number): number => x * 3; const subtract2 = (x: number): number => x - 2; const composedFunctions: ((x: number) => number)[] = [add5, multiply3, subtract2]; const result: number = composedFunctions.reduce((acc, curr) => curr(acc), 10); console.log(result); // Output: 43 ``` 在這個範例中,我們有一個函數陣列,我們希望將其按順序應用到初始值 10。最終結果是按組合順序應用所有函數的結果。 ### 用例 7:實作簡單的類似 Redux 的狀態管理 如果您使用過 Redux,您就會知道它在管理應用程式中的狀態方面有多強大。你猜怎麼了?你可以使用reduce()來實作一個簡單的類似Redux的狀態管理系統。 ``` interface State { count: number; todos: string[]; } interface Action { type: string; payload?: any; } const initialState: State = { count: 0, todos: [], }; const actions: Action[] = [ { type: 'INCREMENT_COUNT' }, { type: 'ADD_TODO', payload: 'Learn Array.reduce()' }, { type: 'INCREMENT_COUNT' }, { type: 'ADD_TODO', payload: 'Master TypeScript' }, ]; const reducer = (state: State, action: Action): State => { switch (action.type) { case 'INCREMENT_COUNT': return { ...state, count: state.count + 1 }; case 'ADD_TODO': return { ...state, todos: [...state.todos, action.payload] }; default: return state; } }; const finalState: State = actions.reduce(reducer, initialState); console.log(finalState); /* Output: { count: 2, todos: ['Learn Array.reduce()', 'Master TypeScript'] } */ ``` 在此範例中,我們有一個初始狀態物件和一組操作。我們定義一個reducer函數,它接受當前狀態和一個動作,並根據動作類型返回一個新狀態。透過使用reduce(),我們可以將每個動作依序應用於狀態,從而得到最終狀態。這就像擁有一個迷你 Redux。 ### 用例 8:產生唯一值 有時,您可能有一個包含重複值的陣列,並且您需要僅提取唯一的值。 reduce() 可以幫助您輕鬆實現這一點。 ``` const numbers: number[] = [1, 2, 3, 2, 4, 3, 5, 1, 6]; const uniqueNumbers: number[] = numbers.reduce((acc, curr) => { if (!acc.includes(curr)) { acc.push(curr); } return acc; }, []); console.log(uniqueNumbers); // Output: [1, 2, 3, 4, 5, 6] ``` 在這裡,我們初始化一個空陣列作為累加器。對於原始陣列中的每個數字,我們使用includes()方法檢查它是否已存在於累加器中。如果沒有,我們將其推入累加器陣列。最終結果是一個僅包含原始陣列中唯一值的陣列。 ### 用例 9:計算平均值 想要計算一組數字的平均值? reduce() 為您提供支援! ``` const grades: number[] = [85, 90, 92, 88, 95]; const average: number = grades.reduce((acc, curr, index, array) => { acc += curr; if (index === array.length - 1) { return acc / array.length; } return acc; }, 0); console.log(average); // Output: 90 ``` 在此範例中,我們將累加器初始化為 0。當我們到達最後一個元素時(使用索引和 array.length 檢查),我們將累加器除以成績總數來計算平均值。 性能考量🏎️ ------ 雖然 Array.reduce() 非常強大且用途廣泛,但了解潛在的效能缺陷非常重要,尤其是在處理大型陣列或複雜操作時。一個常見的陷阱是在每次reduce()迭代中建立新的物件或陣列,這可能會導致過多的記憶體分配並影響效能。 例如,考慮以下程式碼: ``` const numbers: number[] = [1, 2, 3, 4, 5]; const doubledNumbers: number[] = numbers.reduce((acc, curr) => { return [...acc, curr * 2]; }, []); console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10] ``` 在本例中,我們使用展開運算子 (...) 在每次迭代中建立一個新陣列,這可能會效率低下。相反,我們可以透過直接改變累加器陣列來優化程式碼: ``` const numbers: number[] = [1, 2, 3, 4, 5]; const doubledNumbers: number[] = numbers.reduce((acc, curr) => { acc.push(curr * 2); return acc; }, []); console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10] ``` 透過使用 push() 來改變累加器陣列,我們可以避免在每次迭代中建立新陣列,從而獲得更好的效能。 類似地,在處理物件時,直接改變累加器物件比使用擴充運算子建立新物件更有效: ``` const people: Person[] = [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }, { name: 'Charlie', age: 25 }, { name: 'Dave', age: 30 } ]; const groupedByAge: { [key: number]: Person[] } = people.reduce((acc, curr) => { if (!acc[curr.age]) { acc[curr.age] = []; } acc[curr.age].push(curr); return acc; }, {}); ``` 透過直接改變累加器物件,我們優化了reduce()操作的效能。 然而,值得注意的是,在某些情況下,在每次迭代中建立新的物件或陣列可能是必要的或更具可讀性。根據您的具體用例和您正在使用的資料大小,在效能和程式碼清晰度之間取得平衡非常重要。 結論 -- 你有它。九個令人難以置信的用例展示了 Array.reduce() 的強大功能和多功能性。從將數字求和到展平陣列、對物件進行分組到建立查找映射、對出現次數進行計數到組合函數,甚至實現狀態管理和計算平均值, `Array.reduce()`被證明是js 工具包中的強大工具。 你怎麼認為?您最喜歡的陣列方法是什麼? 感謝您的閱讀,願 reduce() 的力量與您同在。 ✨🐐✨ --- 原文出處:https://dev.to/mattlewandowski93/arrayreduce-is-goated-1f1j

15 個 JavaScript 日常操作的實用、簡潔寫法

這裡有多種簡短而強大的 JavaScript 技巧,可以最大限度地提高生產力 ⚡️ 並最大限度地減少痛苦 🩸。 讓我們深入研究看看🤘 原文出處:https://dev.to/ironcladdev/15-killer-js-techniques-youve-probably-never-heard-of-1lgp ### 唯一陣列 過濾掉陣列中的重複值。 ``` const arr = ["a", "b", "c", "d", "d", "c", "e"] const uniqueArray = Array.from(new Set(arr)); console.log(uniqueArray); // ['a', 'b', 'c', 'd', 'e'] ``` ### 唯一的物件陣列 `Set` 物件不允許您過濾掉重複的物件,因為每個物件都是不同的。 `JSON.stringify` 在這裡幫我們解決了這個問題。 ``` const arr = [{ key: 'value' }, { key2: 'value2' }, { key: 'value' }, { key3: 'value3' }]; const uniqueObjects = Array.from( new Set( arr.map(JSON.stringify) ) ).map(JSON.parse) console.log(uniqueObjects); ``` 在 [此評論](https://dev.to/jonrandy/comment/24ojn) 中查看更有效但稍長的方法。 ### 陣列迭代器索引 通過 `.map` 和 `.forEach` javascript 迭代函數,您可以獲得每個項目的索引。 ``` const arr = ['a', 'b', 'c']; const letterPositions = arr.map( (char, index) => `${char} is at index ${index}` ) ``` ### 按字元數拆分字串 我們可以使用 `.match` 正則表達式函數將字串拆分為 `n` 個字符。 ``` const str = "asdfghjklmnopq"; const splitPairs = str.match(/.{1,2}/g); console.log(splitPairs); // ['as', 'df', 'gh', 'jk', 'lm', 'no', 'pq'] ``` ### 用不同的字元拆分字串 另一個使用 .match 的正則表達式 hack 允許您將像“aabbc”這樣的字串拆分為陣列“[”aa”,“bb”,“c”]`。 ``` const str = "abbcccdeefghhiijklll"; const splitChars = str.match(/(.)\1*/g); console.log(splitChars); // ['a', 'bb', 'ccc', 'd', 'ee', 'f', 'g', 'hh', 'ii', 'j', 'k', 'lll'] ``` ### 遍歷物件 `Object.entries` 允許我們將 JSON 物件轉換為鍵值對陣列,從而使我們能夠使用循環或陣列迭代器對其進行迭代。 ``` const obj = { "key1": "value1", "key2": "value2", "key3": "value3" }; const iteratedObject = Object.entries(obj) .map(([key, value]) => `${key} = ${value}`); console.log(iteratedObject); // ['key1 = value1', 'key2 = value2', 'key3 = value3'] ``` ### 鍵值陣列到物件 您可以使用“Object.fromEntries”將“Object.entryified”鍵值對陣列轉換回物件 ``` const entryified = [ ["key1", "value1"], ["key2", "value2"], ["key3", "value3"] ]; const originalObject = Object.fromEntries(entryified); console.log(originalObject); // { key1: 'value1', ... } ``` ### 發生次數計數 您可能想計算一個專案在陣列中出現的次數。我們可以使用帶有迭代器的 .filter 函數來完成此操作。 ``` const occurrences = ["a", "b", "c", "c", "d", "a", "a", "e", "f", "e", "f", "g", "f", "f", "f"]; // creating a unique array to avoid counting the same char more than once const unique = Array.from(new Set(occurrences)); const occurrenceCount = Object.fromEntries( unique.map(char => { const occurrenceCount = occurrences.filter(c => c === char).length; return [char, occurrenceCount] }) ) console.log(occurrenceCount); // { a: 3, b: 1, c: 2, ... } ``` 在 [此評論](https://dev.to/jonrandy/comment/24ojn) 中查看可靠的單行程式碼以執行此操作! ### 替換回調 `.replace` 函數並不限制您只能用固定字串替換。您可以將回調傳遞給它並使用匹配的子字串。 ``` const string = "a dog went to dig and dug a doggone large hole"; const replacedString = string.replace(/d.g/g, str => str + "gy") console.log(replacedString); // a doggy went to diggy and duggy a doggygone large hole ``` ### 條件串接 你們中的許多人都熟悉在 JS 中遇到未定義的錯誤,條件連結可以防止很多這種情況的發生。 > **可選連結** (`?.`) 運算符存取物件的屬性或呼叫函數。如果使用此運算符存取的對像或呼叫的函數未定義或為空,則表達式短路併計算為未定義,而不是拋出錯誤。 ``` const obj = { "a": "aaaaaaa", "b": null }; console.log(obj.b.d); // throws an error console.log(obj.b?.d); // returns undefined ``` ### 限定一個數字 通常,您可能需要將數字限制在特定範圍內。每次需要時都用三元運算符來做是一件很痛苦的事情。函數要乾淨得多。 ``` const constrain = (num, min, max) => { if(num < min) return min; else if(num > max) return max; else return num; } constrain(5, 1, 3) // 3 constrain(2, 1, 5) // 2 constrain(0, -100, 100) // 0 ``` 一個更好的方法是像這樣使用 `Math.min` 和 `Math.max`: ``` const constrain = (num, min, max) => Math.min(Math.max(num, min), max) ``` ### 索引陣列的前後 `.at` 函數允許您使用正數和負數從頭到尾對陣列進行索引。 ``` const arr = [1, 2, 3, 4, 5]; arr.at(0) // 1 arr.at(1) // 2 arr.at(-1) // 5 arr.at(-2) // 4 ``` ### 按字母順序排序 按字母順序對字串陣列進行排序 ``` const words = ["javascript", "typescript", "python", "ruby", "swift", "go", "clojure"]; const sorted = words.sort((a, b) => a.localeCompare(b)); console.log(sorted); // ['clojure', 'go', 'javascript', 'python', 'ruby', 'swift', 'typescript'] ``` 💡 **提示**:您可以通過將 `a.localeCompare(b)` 切換為 `b.localeCompare(a)` 來切換升序和降序 ### 按 Truthy/Falsy 值排序 您可以按真值/假值對陣列進行排序,將具有真值的值放在最前面,然後是假值。 ``` const users = [ { "name": "john", "subscribed": false }, { "name": "jane", "subscribed": true }, { "name": "jean", "subscribed": false }, { "name": "george", "subscribed": true }, { "name": "jelly", "subscribed": true }, { "name": "john", "subscribed": false } ]; const subscribedUsersFirst = users.sort((a, b) => Number(b.subscribed) - Number(a.subscribed)) ``` `Number(false)` 等於 0,`Number(true)` 等於 1。這就是我們如何通過排序函數傳遞它。 ### 四捨五入到 `n` 位 您可以使用 .toFixed 將小數四捨五入為 n 位。請注意,`.toFixed` 將數字轉換為字串,因此我們必須將其重新解析為數字。 ``` console.log(Math.PI); // 3.141592653589793 console.log(Number(Math.PI.toFixed(2))) ``` --- 感謝閱讀✨!