簡體   English   中英

Javascript 中的反向數組而不改變原始數組

[英]Reverse array in Javascript without mutating original array

Array.prototype.reverse原地反轉數組的內容(帶有突變)...

是否有類似的簡單策略來反轉數組而不改變原始數組的內容(無突變)?

您可以使用slice()進行復制,然后使用reverse()

var newarray = array.slice().reverse();

 var array = ['a', 'b', 'c', 'd', 'e']; var newarray = array.slice().reverse(); console.log('a', array); console.log('na', newarray);

在 ES6 中:

const newArray = [...array].reverse()

另一個 ES6 變體:

我們還可以使用.reduceRight()創建一個反轉數組,而無需實際反轉它。

 let A = ['a', 'b', 'c', 'd', 'e', 'f']; let B = A.reduceRight((a, c) => (a.push(c), a), []); console.log(B);

有用的資源:

試試這個遞歸解決方案:

const reverse = ([head, ...tail]) => 
    tail.length === 0
        ? [head]                       // Base case -- cannot reverse a single element.
        : [...reverse(tail), head]     // Recursive case

reverse([1]);               // [1]
reverse([1,2,3]);           // [3,2,1]
reverse('hello').join('');  // 'olleh' -- Strings too!                              

使用.reduce()和傳播的 ES6 替代方案。

const foo = [1, 2, 3, 4];
const bar = foo.reduce((acc, b) => ([b, ...acc]), []);

基本上它所做的就是用 foo 中的下一個元素創建一個新數組,並在 b 之后為每次迭代傳播累積的數組。

[]
[1] => [1]
[2, ...[1]] => [2, 1]
[3, ...[2, 1]] => [3, 2, 1]
[4, ...[3, 2, 1]] => [4, 3, 2, 1]

或者.reduceRight()如上所述,但沒有.push()突變。

const baz = foo.reduceRight((acc, b) => ([...acc, b]), []);

有多種方法可以在不修改的情況下反轉數組。 其中兩個是

var array = [1,2,3,4,5,6,7,8,9,10];

// Using Splice
var reverseArray1 = array.splice().reverse(); // Fastest

// Using spread operator
var reverseArray2 = [...array].reverse();

// Using for loop 
var reverseArray3 = []; 
for(var i = array.length-1; i>=0; i--) {
  reverseArray.push(array[i]);
}

性能測試http://jsben.ch/guftu

const newArr = Array.from(originalArray).reverse();

const arrayCopy = Object.assign([], array).reverse()

這個解決方案:

- 成功復制數組

- 不改變原始數組

- 看起來它正在做它正在做的事情

僅出於演示目的使用變量交換就地反轉(但如果您不想變異,則需要一個副本)

const myArr = ["a", "b", "c", "d"];
const copy = [...myArr];
for (let i = 0; i < (copy.length - 1) / 2; i++) {  
    const lastIndex = copy.length - 1 - i; 
    [copy[i], copy[lastIndex]] = [copy[lastIndex], copy[i]] 
}

雖然array.slice().reverse()是我自己在無法使用庫的情況下使用的,但它在可讀性方面並不是那么好:我們使用的是命令式邏輯,閱讀代碼的人必須仔細考慮. 還考慮到sort也存在同樣的問題,這里有充分的理由使用實用程序庫。

您可以使用來自fp-ts的函數pipe我自己編寫的庫 它通過多個函數傳遞一個值,因此pipe(x, a, b)等價於b(a(x)) 使用此函數,您可以編寫

pipe(yourArray, reverseArray)

其中reverseArray是一個基本上執行.slice().reverse()的函數,即不可變地反轉數組。 一般來說, pipe可以讓你做點鏈接的等價物,但不限於數組原型上可用的方法。

有一個新的tc39 提案,它向Array添加了一個toReversed方法,該方法返回數組的副本並且不修改原始數組。

提案示例:

const sequence = [1, 2, 3];
sequence.toReversed(); // => [3, 2, 1]
sequence; // => [1, 2, 3]

由於它目前處於第 3 階段,它可能很快就會在瀏覽器引擎中實現,但與此同時,這里core-js中提供了一個 polyfill。

是否有類似簡單的策略來反轉數組而不改變原始數組的內容(沒有突變)?

是的,有一種方法可以通過使用to[Operation]返回一個應用了操作的新集合來實現這一點(目前處於第 3 階段,即將推出)。

實施將如下所示

const arr = [5, 4, 3, 2, 1];

const reversedArr = arr.toReverse();

console.log(arr); // [5, 4, 3, 2, 1]

console.log(reversedArr); // [1, 2, 3, 4, 5]

進入 2022 年,這是當今最高效的解決方案(性能最高,並且沒有額外的內存使用)。


對於任何ArrayLike類型,邏輯上最快的反轉方式是將其包裝到一個反轉的可迭代對象中:

function reverse<T>(input: ArrayLike<T>): Iterable<T> {
    return {
        [Symbol.iterator](): Iterator<T> {
            let i = input.length;
            return {
                next(): IteratorResult<T> {
                    return i
                        ? {value: input[--i], done: false}
                        : {value: undefined, done: true};
                },
            };
        },
    };
}

通過這種方式,您可以反向迭代任何ArraystringBuffer ,而無需對反向數據進行任何額外的復制或處理:

for(const a of reverse([1, 2, 3])) {
    console.log(a); //=> 3 2 1
}

這是最快的方法,因為你不復制數據,根本不做任何處理,你只是邏輯反轉。

不是最好的解決方案,但它有效

 Array.prototype.myNonMutableReverse = function () { const reversedArr = []; for (let i = this.length - 1; i >= 0; i--) reversedArr.push(this[i]); return reversedArr; }; const a = [1, 2, 3, 4, 5, 6, 7, 8]; const b = a.myNonMutableReverse(); console.log("a",a); console.log("////////") console.log("b",b);

INTO純Javascript:

function reverseArray(arr, num) {
  var newArray = [];
  for (let i = num; i <= arr.length - 1; i++) {
    newArray.push(arr[i]);
  }

  return newArray;
}

這里有一些很酷的方法來反轉數組

es6:

const reverseArr = [1,2,3,4].sort(()=>1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM