數(shù)組是編程中一種基本且強大的數(shù)據(jù)結(jié)構(gòu)。它們的力量不僅僅來自于存儲多個對象或值的能力。它們還公開了各種工具,使操作和使用它們所包含的數(shù)據(jù)變得容易。
我們經(jīng)常需要更改數(shù)組以滿足特定需求。例如,您可能需要重新組織數(shù)組中的對象,以便它按特定屬性的值排序,或者您可能需要將多個數(shù)組合并為單個數(shù)組。在許多情況下,您可能需要將一個對象數(shù)組完全轉(zhuǎn)換為另一個完全不同對象的數(shù)組。
在本教程中,您將了解 JavaScript 提供的用于合并、復(fù)制、轉(zhuǎn)換和過濾數(shù)組的工具。然而,在開始之前,我必須指出,雖然我使用術(shù)語“合并”、“轉(zhuǎn)換”、“轉(zhuǎn)換”和“過濾”,但這些過程很少更改現(xiàn)有數(shù)組。相反,他們創(chuàng)建一個新數(shù)組,其中包含合并、轉(zhuǎn)換、轉(zhuǎn)換和過濾的數(shù)據(jù),使原始數(shù)組保持不變的原始格式。
跳轉(zhuǎn)到本節(jié)內(nèi)容:
立即學(xué)習(xí)“Java免費學(xué)習(xí)筆記(深入)”;
- 合并數(shù)組
- 復(fù)制數(shù)組
- 將數(shù)組轉(zhuǎn)換為字符串
- 轉(zhuǎn)換數(shù)組
- 過濾數(shù)組
合并數(shù)組
也許您正在處理來自不同來源的數(shù)據(jù),或者您可能有多個數(shù)組并希望將它們組合成一個數(shù)組,以便更輕松地處理它們。無論出于何種原因,有時您都需要將多個數(shù)組合并為一個數(shù)組。 JavaScript 為我們提供了兩種組合數(shù)組的方法。您可以使用 concat() 方法或展開運算符 (…)。
concat() 方法用于合并兩個或多個數(shù)組,并返回一個包含合并數(shù)組元素的新數(shù)組。新數(shù)組將首先由您調(diào)用該方法的數(shù)組對象中的元素填充。然后,它將由您傳遞給該方法的數(shù)組對象的元素填充。例如:
const Array1 = [1, 2, 3]; const array2 = [4, 5, 6]; const mergedArray = array1.concat(array2); console.log(mergedArray); // output: [1, 2, 3, 4, 5, 6]
在這段代碼中,我們有兩個數(shù)組,array1 和 array2。我們使用 concat() 方法將這些數(shù)組合并到一個名為 mergedArray 的新數(shù)組中,您可以看到生成的數(shù)組包含元素 [1, 2, 3, 4, 5, 6]。下面的示例更改代碼,以便在 array2 上調(diào)用 concat() 方法:
const array1 = [1, 2, 3]; const array2 = [4, 5, 6]; const mergedArray2 = array2.concat(array1); console.log(mergedArray2); // output: [4, 5, 6, 1, 2, 3]
請注意,在此代碼中,結(jié)果數(shù)組中的元素的順序不同:[4, 5, 6, 1, 2, 3]。因此,如果元素順序?qū)δ苤匾垊?wù)必按照您想要的順序使用 concat() 。
另一方面,擴展運算符允許您擴展數(shù)組的元素,并且可以在新的數(shù)組文字中使用它來合并數(shù)組。例如:
const array1 = [1, 2, 3]; const array2 = [4, 5, 6]; const mergedArray = [...array1, ...array2]; console.log(mergedArray); // output: [1, 2, 3, 4, 5, 6]
在這里,我們再次有兩個數(shù)組,array1 和 array2,但我們使用擴展運算符將它們合并到一個名為 mergedArray 的新數(shù)組中。最終結(jié)果與第一個 concat() 示例相同,但使用這種方法可以讓您(以及那些閱讀代碼的人)更清楚地了解 mergedArray 是如何構(gòu)建和填充的。
復(fù)制數(shù)組
您可能想要復(fù)制數(shù)組的原因有多種。您可能希望保留數(shù)組的原始數(shù)據(jù)(如果它們是簡單值),或者您可能希望避免使用或操作數(shù)組對象本身帶來的任何意外副作用。不管出于什么原因,JavaScript 使得創(chuàng)建數(shù)組的副本變得非常容易。
要創(chuàng)建數(shù)組的副本,可以使用 slice() 方法。此方法返回您調(diào)用它的數(shù)組的淺表副本(稍后詳細(xì)介紹)。例如:
const originalArray = [1, 2, 3, 4, 5]; const copiedArray = originalArray.slice(); console.log(copiedArray); // output: [1, 2, 3, 4, 5]
這段代碼定義了一個名為originalArray的數(shù)組,我們使用slice()方法創(chuàng)建它的副本,而不傳遞任何參數(shù)。 copiedArray 對象包含與原始值相同的值,但它是一個完全不同的數(shù)組對象。
您還可以使用 slice() 方法通過指定開始和結(jié)束索引來提取數(shù)組的一部分。
const originalArray = [1, 2, 3, 4, 5]; const slicedArray = originalArray.slice(1, 4); console.log(slicedArray); // output: [2, 3, 4]
在此示例中,我們創(chuàng)建一個切片數(shù)組,其中包含原始數(shù)組從索引 1 到索引 3 的元素(不包括傳遞給 slice() 方法的結(jié)束索引)。
什么是淺拷貝?
淺拷貝是指創(chuàng)建一個新的對象或數(shù)組,它是原始對象或集合的副本,但僅限于第一級。換句話說,淺拷貝復(fù)制原始對象的結(jié)構(gòu),但不復(fù)制其中包含的對象或元素。
當(dāng)您創(chuàng)建數(shù)組的淺表副本時,新數(shù)組將擁有自己的一組引用,對與原始數(shù)組相同的對象或元素進行引用。這意味著如果原始數(shù)組包含簡單值(例如數(shù)字、字符串或布爾值),則淺拷貝將有效地創(chuàng)建具有相同值的新數(shù)組。但是,如果原始數(shù)組包含對象或其他引用類型(例如其他數(shù)組或?qū)ο螅?,則淺復(fù)制將僅復(fù)制對這些對象的引用,而不是對象本身。因此,對原始數(shù)組中的對象所做的任何更改也將反映在淺拷貝中,反之亦然,因為它們?nèi)匀灰脙?nèi)存中的相同對象。
相比之下,深層復(fù)制創(chuàng)建一個新的對象或集合,它是原始對象或集合的完整、獨立的副本,包括所有嵌套的對象或元素。這意味著對原始數(shù)組中的對象所做的更改不會影響深層復(fù)制,反之亦然,因為它們在內(nèi)存中擁有自己的對象集。
下面是一個例子來說明差異:
const originalArray = [1, 2, { a: 3 }]; const shallowCopy = originalArray.slice(); const deepCopy = json.parse(JSON.stringify(originalArray)); originalArray[2].a = 4; console.log(shallowCopy); // output: [1, 2, { a: 4 }] console.log(deepCopy); // output: [1, 2, { a: 3 }]
在此示例中,shallowCopy反映對原始數(shù)組所做的更改,而deepCopy不受影響。
將數(shù)組轉(zhuǎn)換為字符串
數(shù)組是一種編程構(gòu)造,很多時候我們需要將數(shù)組轉(zhuǎn)換為字符串。也許我們需要向用戶呈現(xiàn)數(shù)組的內(nèi)容。也許我們需要將數(shù)組的內(nèi)容序列化為 JSON 以外的格式。
通過使用 join() 方法,您可以將數(shù)組轉(zhuǎn)換為字符串。默認(rèn)情況下,元素以逗號分隔,但您可以通過將字符串作為參數(shù)傳遞給 join() 方法來指定自定義分隔符。例如:
const fruitArray = ['apple', 'banana', 'cherry']; const fruitString = fruitArray.join(', '); console.log(fruitString); // output: "apple, banana, cherry"
在此示例中,我們有一個名為 fruitArray 的數(shù)組,我們使用 join() 方法將其轉(zhuǎn)換為字符串自定義分隔符 – 逗號后跟空格。
使用 join() 的一個更有用的示例是從包含 URL 查詢字符串參數(shù)的數(shù)組中輸出 URL 查詢字符串,如下所示:
const queryParamsArray = [ 'search=JavaScript', 'page=1', 'sort=relevance', ]; const queryString = queryParamsArray.join('&'); const url = 'https://example.com/api?' + queryString; console.log(url); // output: "https://example.com/api?search=JavaScript&page=1&sort=relevance"
在此代碼中,我們有一個名為 queryParamsArray 的數(shù)組,其中包含一組查詢字符串參數(shù)。然后,我們使用 join() 方法將數(shù)組的元素與 & 分隔符連接起來,形成一個查詢字符串。最后,我們通過將查詢字符串附加到基本 URL 來構(gòu)建完整的 URL。
生成 URL 查詢參數(shù)字符串是使用 join() 的常見用例。但是,您將使用一組復(fù)雜的對象,而不是像本示例中所示的簡單的預(yù)定義字符串,然后必須將其轉(zhuǎn)換為可以連接在一起的字符串?dāng)?shù)組。
轉(zhuǎn)換數(shù)組
轉(zhuǎn)換數(shù)組的能力是 JavaScript 中最有用、最強大的功能之一。正如我在本教程前面提到的,您并不是真正轉(zhuǎn)換數(shù)組,而是創(chuàng)建一個包含轉(zhuǎn)換后的對象或值的新數(shù)組。原始數(shù)組未修改。
要轉(zhuǎn)換數(shù)組,請使用 map() 方法。它接受回調(diào)函數(shù)作為參數(shù),并為數(shù)組中的每個元素執(zhí)行該函數(shù)。
map(function (currentElement[, index, array]));
回調(diào)函數(shù)可以接受以下三個參數(shù):
- currentElement:當(dāng)前要轉(zhuǎn)換的元素(必填)
- index:當(dāng)前元素的索引(可選)
- array:調(diào)用 map() 方法的數(shù)組(可選)
然后,回調(diào)函數(shù)的返回值將作為元素存儲在新數(shù)組中。例如:
const numbers = [1, 2, 3, 4, 5]; function square(number) { return number * number; } const squaredNumbers = numbers.map(square); console.log(squaredNumbers); // output: [1, 4, 9, 16, 25]
在此代碼中,我們有一個名為 numbers 的數(shù)組,并聲明一個名為 square 的函數(shù),該函數(shù)將數(shù)字作為輸入并返回該數(shù)字的平方。我們將 square 函數(shù)傳遞給 numbers.map() 以創(chuàng)建一個名為 squaredNumbers 的新數(shù)組,其中包含原始數(shù)字的平方值。 p>
但是讓我們看一個從對象數(shù)組構(gòu)建 URL 查詢字符串的示例。原始數(shù)組將包含具有 param (對于參數(shù)名稱)和 value (對于參數(shù)值)屬性的對象。
const queryParams = [ { param: 'search', value: 'JavaScript' }, { param: 'page', value: 1 }, { param: 'sort', value: 'relevance' }, ]; function createParams(obj) { return obj.param + '=' + obj.value; } const queryStringArray = queryParams.map(createParams); const queryString = queryStringArray.join('&'); const url = 'https://example.com/api?' + queryString; console.log(url); // output: "https://example.com/api?search=JavaScript&page=1&sort=relevance"
在此示例中,我們有一個名為 queryParams 的數(shù)組,其中包含我們要轉(zhuǎn)換為查詢字符串的對象。我們聲明一個名為 createParams 的函數(shù),它接受一個對象作為輸入并返回格式為“param=value”的字符串。然后,我們使用 map() 方法將 createParams?函數(shù)應(yīng)用于原始數(shù)組中的每個對象,從而創(chuàng)建一個名為 queryStringArray 的新數(shù)組。
接下來,我們 join() queryStringArray 創(chuàng)建最終的查詢字符串,使用 & 分隔符分隔每個 param=value 對,然后我們通過將查詢字符串附加到來構(gòu)造完整的 URL基本 URL。
使用 map() 方法是處理數(shù)組的重要部分,但有時我們只需要處理數(shù)組中的幾個元素。
過濾數(shù)組
Filter() 方法允許您創(chuàng)建一個僅包含滿足給定條件的元素的新數(shù)組。這是通過將回調(diào)函數(shù)傳遞給 filter() 方法來實現(xiàn)的,該方法測試原始數(shù)組中的每個元素。如果回調(diào)函數(shù)返回true,則該元素包含在新數(shù)組中;如果返回 false,則排除該元素。
回調(diào)函數(shù)使用與 map() 方法的回調(diào)函數(shù)相同的簽名:
filter(function(currentElement[, index, array]));
currentElement 參數(shù)是必需的,但 index 和 array 是可選的。例如:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; function isEven(number) { return number % 2 === 0; } const evenNumbers = numbers.filter(isEven); console.log(evenNumbers); // output: [2, 4, 6, 8, 10]
在此示例中,我們有一個名為 numbers 的數(shù)組。我們聲明一個名為 isEven 的函數(shù),它接受一個數(shù)字作為輸入,如果數(shù)字是偶數(shù)(即能被 2 整除),則返回 true ,否則返回 false 。我們通過使用 isEven 函數(shù)作為 filter() 方法的回調(diào)函數(shù)來過濾原始數(shù)組,從而創(chuàng)建一個名為 evenNumbers 的新數(shù)組。生成的 evenNumbers 數(shù)組僅包含原始數(shù)組中的偶數(shù)。
filter() 方法是處理數(shù)組的強大工具,允許您輕松提取相關(guān)數(shù)據(jù)或根據(jù)特定條件創(chuàng)建數(shù)組的子集。
結(jié)論
數(shù)組是 JavaScript 中最通用、最有用的對象之一,因為我們有工具可以輕松地合并、復(fù)制、轉(zhuǎn)換、轉(zhuǎn)換和過濾它們。這些技術(shù)中的每一種都有特定的用途,您可以通過各種方式將它們組合起來,以在 JavaScript 應(yīng)用程序中有效地操作和處理數(shù)組。通過理解和應(yīng)用這些方法,您將能夠更好地應(yīng)對涉及數(shù)組的各種編程挑戰(zhàn)。
當(dāng)您繼續(xù)發(fā)展 JavaScript 技能時,請記住練習(xí)使用這些數(shù)組方法并探索該語言中可用的其他內(nèi)置數(shù)組函數(shù)。這將幫助您更加精通 JavaScript,并使您能夠編寫更高效、干凈且可維護的代碼。快樂編碼!