[英]Count number of elements in TypedArray in JavaScript
下面的代碼是從Web Developers Professional JavaScript一書中摘錄的代碼的修改版本。
// First argument is the type of array that should be returned // Remaining arguments are all the typed arrays that should be concatenated function numElements(typedArrayConstructor, ...typedArrays) { // Count the total elements in all arrays return typedArrays.reduce((x,y) => (x.length || x) + y.length); } console.log(numElements(Int32Array, Int8Array.of(1, 2, 3), Int16Array.of(4, 5, 6), Float32Array.of(7, 8, 9)));
我的問題是(x.length || x)
做什么的? 為什么我們需要對x.length
和x
執行or
操作?
Pointy 的回答還有一點解釋:
||
在 JavaScript 中不僅僅是邏輯 OR 操作,它處理“真/假”值,而不僅僅是布爾值。
undefined
是假的。 當||
的第一個操作數為假,則計算第二個操作數,並成為表達式的結果。 因此undefined || 0
undefined || 0
等於 0。
在您的示例代碼中,這意味着當x
為 0 時,您添加 0,並獲得正確的數字結果。 如果您嘗試將undefined
添加到另一個數字,那么您的所有計算都將在此之后變為NaN
。
當.reduce()
只用一個參數調用時,第一次迭代使用元素 0 作為第一個回調參數,元素 1 作為第二個。
在您的情況下,這意味着在第一次迭代中, x
將是數組之一(請注意, y
始終是一個數組)。 因此,這個小表達式通過利用以下事實來區分何時是第一次迭代和何時是后續迭代
someNumber.length
總是undefined
。 (正如在另一個答案中正確指出的那樣,重要的是要記住(undefined || x)
將始終是x
,無論其值是什么。)因此,在后續迭代中, x
是數組長度的運行總和。
.reduce()
可以寫成如下:
return typedArrays.reduce((x,y) => x + y.length, 0);
通過將第二個參數 (0) 傳遞給.reduce()
,第一個回調調用將與其他調用相同,並且x
將始終是一個數字。
如果 x 有任何元素並且 x 存在,則使用總和中的長度。 否則,如果長度未定義,則返回當前元素 x
示例 1: - 發生在 reduce 循環的第一次迭代中
x 是數組 [1, 2, 3]
x.length || x -> returns the length of array or current total
// summation of code would do the following
firsthArrayLength + secondArrayLength = newTotal
示例 2: - 發生在 reduce 循環的其余迭代中
x 是整數 5
x.length || x -> returns x since length of integer is undefined
// summation of code would do the following
currentTotal + curLength = newTotal
注意:請記住,在此示例中,如果任何數組為空或未定義,則它將拋出,因為我們無法訪問未定義或空的屬性長度
太悲傷了,這是從書中摘錄的。 使用reduce
和||
那樣的魯莽和不專業——
// First argument is the type of array that should be returned // Remaining arguments are all the typed arrays that should be concatenated const numElements = (constructor, ...arrs) => new constructor(arrs.reduce((r, a) => r + a.length, 0)) const result = numElements ( Int32Array , Int8Array.of(1, 2, 3) , Int16Array.of(4, 5, 6) , Float32Array.of(7, 8, 9) ) console.log(result.constructor) console.log(result) // Int32Array // { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
該函數的描述說它應該連接其他數組,而不僅僅是初始化一個空類型的數組。 這可能是這樣的——
// First argument is the type of array that should be returned // Remaining arguments are all the typed arrays that should be concatenated const concatMixed = (constructor, ...arrs) => { const r = new constructor(arrs.reduce((r, a) => r + a.length, 0)) let i = 0 for (const a of arrs) for (const val of a) r[i++] = val return r } const result = concatMixed ( Int32Array , Int8Array.of(1, 2, 3) , Int16Array.of(4, 5, 6) , Float32Array.of(7.1, 8.2, 9.3) ) console.log(result.constructor) console.log(result) // Int32Array // { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.