Czy istnieje sposób użycia map () na tablicy w odwrotnej kolejności z javascript?


100

Chcę użyć tej map()funkcji na tablicy javascript, ale chciałbym, aby działała w odwrotnej kolejności.

Powodem jest to, że renderuję skumulowane komponenty React w projekcie Meteor i chciałbym, aby element najwyższego poziomu był renderowany jako pierwszy, podczas gdy reszta ładuje obrazy poniżej.

var myArray = ['a', 'b', 'c', 'd', 'e'];
myArray.map(function (el, index, coll) {
    console.log(el + " ")
});

drukuje, a b c d eale chciałbym, żeby była wydrukowana mapReverse ()e d c b a

Jakieś sugestie?


2
Dlaczego nie macie reversetablicy?
Jan

2
Aby uporządkować elementy, ustawiam indeks Z według indeksu tablicy. Przypuszczam, że mógłbym ustawić indeks Z na ujemny.
Robin Newhouse,

Brzmi jak dobry pomysł.
Jan

Na marginesie, czy faktycznie używasz mapzwracanej tablicy ? W przeciwnym razie powinieneś rozważyć forEach.
kanon

1
Możesz uzyskać dostęp do odwrotnego elementu w wywołaniu zwrotnym mapy:console.log(coll[coll.length - index - 1] + " ")
le_m

Odpowiedzi:


158

Jeśli nie chcesz odwracać oryginalnej tablicy, możesz zrobić jej płytką kopię, a następnie zmapować odwróconą tablicę,

myArray.slice(0).reverse().map(function(...

Skończyło się na tym, że użyłem ujemnego indeksu do określenia indeksu z, ale sposób, w jaki sformułowałem pytanie, jest najbardziej poprawny.
Robin Newhouse,

3
Dlaczego potrzebujemy .slice (0)? Dlaczego nie myArray.reverse () zamiast myArray.slice (0) .reverse ()? Wygląda na to, że odpowiedź na mój komentarz jest tutaj: stackoverflow.com/questions/5024085/…
Haradzieniec

Haradzieniec - To się zgadza ze szczegółami dotyczącymi tego, jak zostało sformułowane pierwotne pytanie, ponieważ pierwotna kolejność była potrzebna do ustawienia właściwości css Z-index, ale wydrukowana w odwrotnej kolejności.
AdamCooper86

Nie slice(0)jest potrzebny, ponieważ reverse()zwraca nową tablicę i nie modyfikuje bieżącej tablicy. @ AdamCooper86 Mam nadzieję, że to zmienisz.
Fahd Lihidheb

5
@FahdLihidheb reverse()NIE modyfikuje oryginalnej tablicy.
Ferus

20

W ogóle nie mutując tablicy, oto jedno liniowe rozwiązanie O (n), które wymyśliłem:

myArray.map((val, index, array) => array[array.length - 1 - index]);

valnie jest tutaj używany, więc nie sądzę, aby tego szukał OP? (to wciąż dobre rozwiązanie)
Paul Razvan Berg

dodatkowo trzeci argument funkcji map () to sama tablica
Knut

19

Możesz użyć Array.prototype.reduceRight()

var myArray = ["a", "b", "c", "d", "e"];
var res = myArray.reduceRight(function (arr, last, index, coll) {
    console.log(last, index);
    return (arr = arr.concat(last))
}, []);
console.log(res, myArray)


noice (jeśli mimo wszystko chcesz wykonać redukcję) - MDN: Metoda reduRight () stosuje funkcję względem akumulatora i każdej wartości tablicy (od prawej do lewej), aby zredukować ją do jednej wartości.
TamusJRoyce

8

Z nazwaną funkcją zwrotną

const items = [1, 2, 3]; 
const reversedItems = items.map(function iterateItems(item) {
  return item; // or any logic you want to perform
}).reverse();

Skrót (bez nazwanej funkcji zwrotnej) - składnia strzałki, ES6

const items = [1, 2, 3];
const reversedItems = items.map(item => item).reverse();

Oto wynik

wprowadź opis obrazu tutaj


mapa jest używana jako płytka kopia
TamusJRoyce

7

Innym rozwiązaniem mogłoby być:

const reverseArray = (arr) => arr.map((_, idx, arr) => arr[arr.length - 1 - idx ]);

Zasadniczo pracujesz z indeksami tablic


2
Wydaje się, że to dziwna droga, ale podejście redukujRight jest również dziwne, jeśli chcesz mieć dostęp do indeksu oprócz elementu, tak naprawdę nie chcesz robić redukcji itp. W moim przypadku był to najczystsze rozwiązanie.
RealHandy

1
Jeśli musisz wykonać dalsze prace wewnątrz mapy, użycie arr [...] nie wymaga drugiej kopii ani manipulowania oryginalną tablicą. Zapomniałem o trzecim parametrze. Czego szukałem!
TamusJRoyce

6

Wolę raz napisać funkcję mapReverse, a następnie jej użyć. Nie ma też potrzeby kopiowania tablicy.

function mapReverse(array, fn) {
    return array.reduceRight(function (result, el) {
        result.push(fn(el));
        return result;
    }, []);
}

console.log(mapReverse([1, 2, 3], function (i) { return i; }))
// [ 3, 2, 1 ]
console.log(mapReverse([1, 2, 3], function (i) { return i * 2; }))
// [ 6, 4, 2 ]

1
function mapRevers(reverse) {
    let reversed = reverse.map( (num,index,reverse) => reverse[(reverse.length-1)-index] );
    return reversed;
}

console.log(mapRevers(myArray));

I Przekazujesz tablicę, aby odwzorować Revers, aw funkcji zwracasz odwróconą tablicę. W mapie cb po prostu pobierasz wartości z indeksem liczącym od 10 (długość) do 1 z przekazanej tablicy


Pomocne może być pisemne wyjaśnienie, co robi ten kod.
Pro Q

0

Oto moje rozwiązanie TypeScript, które jest zarówno O (n), jak i bardziej wydajne niż inne rozwiązania, zapobiegając dwukrotnemu uruchomieniu przez tablicę:

function reverseMap<T, O>(arg: T[], fn: (a: T) => O) {
   return arg.map((_, i, arr) => fn(arr[arr.length - i - 1]))
}

W JavaScript:

const reverseMap = (arg, fn) => arg.map((_, i, arr) => fn(arr[arr.length - 1 - i]))

// Or 

function reverseMap(arg, fn) {
    return arg.map((_, i, arr) => fn(arr[arr.length - i - 1]))
}

-1

Możesz najpierw wykonać myArray.reverse ().

var myArray = ['a', 'b', 'c', 'd', 'e'];
myArray.reverse().map(function (el, index, coll) {
    console.log(el + " ")
});

To byłoby moje ogólne rozwiązanie, ale w konfiguracji, której używam, górna karta jest umieszczana z ostatnim indeksem. Myślę, że po prostu lepsze indeksowanie mogłoby rozwiązać problem.
Robin Newhouse,

16
Tak jak uwaga, spowoduje to odwrócenie oryginalnej tablicy w miejscu, co oznacza, że ​​spowoduje to destrukcyjną zmianę kolejności tablicy.
AdamCooper86,

-2

Stare pytanie, ale dla nowych widzów jest to najlepszy sposób na odwrócenie tablicy za pomocą mapy

var myArray = ['a', 'b', 'c', 'd', 'e'];
[...myArray].map(() => myArray.pop());

to modyfikuje oryginalną tablicę
TamusJRoyce

może miałeś na myśli [...myArray].map((_, _, arr) => arr.pop());:?
Madeo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.