Existe uma maneira de usar map () em uma matriz na ordem inversa com javascript?


100

Eu quero usar a map()função em uma matriz javascript, mas gostaria que funcionasse na ordem inversa.

O motivo é que estou renderizando componentes React empilhados em um projeto Meteor e gostaria que o elemento de nível superior renderizasse primeiro enquanto o resto carrega as imagens abaixo.

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

imprime, a b c d emas gostaria que houvesse um mapReverse () que imprimissee d c b a

Alguma sugestão?


2
Por que você não faz reversea matriz?
John,

2
Para ordenar os elementos, defino o índice z pelo índice do array. Suponho que poderia definir o índice z como negativo.
Robin Newhouse,

Parece uma boa ideia.
João,

Em uma nota lateral, você está realmente usando a matriz que mapretorna? Caso contrário, você deve considerar forEach.
cânone

1
Você pode acessar o elemento reverso no retorno de chamada do mapa:console.log(coll[coll.length - index - 1] + " ")
le_m

Respostas:


158

Se você não quiser inverter a matriz original, você pode fazer uma cópia superficial dela e mapear a matriz invertida,

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

Acabei usando apenas o índice negativo para especificar o índice z, mas da forma como elaborei a pergunta, este é o mais correto.
Robin Newhouse,

3
Por que precisamos de .slice (0)? Por que não myArray.reverse () em vez de myArray.slice (0) .reverse ()? Parece que a resposta para meu comentário está aqui: stackoverflow.com/questions/5024085/…
Haradzieniec

Haradzieniec - Vai com os detalhes de como a pergunta original foi formulada, em que a ordem original foi necessária para definir uma propriedade css do Z-index, mas impressa ao contrário.
AdamCooper86

Não slice(0)é necessário reverse()retornar um novo array e não modifica o array atual. @ AdamCooper86 espero que você mude isso.
Fahd Lihidheb

5
@FahdLihidheb reverse()modifica o array original.
Ferus de

20

Sem nenhuma mutação na matriz, aqui está uma solução O (n) de uma linha que eu criei:

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

valnão é usado aqui, então não acho que era isso que o OP estava procurando? (ainda é uma boa solução)
Paul Razvan Berg

além disso, o terceiro argumento de map () é a própria matriz
Knut

19

Você pode usar 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 (se você estiver procurando realizar uma redução de qualquer maneira) - MDN: O método reduceRight () aplica uma função contra um acumulador e cada valor do array (da direita para a esquerda) para reduzi-lo a um único valor.
TamusJRoyce

8

Com função de retorno de chamada nomeada

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

Atalho (sem função de retorno de chamada nomeada) - Sintaxe de seta, ES6

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

Aqui está o resultado

insira a descrição da imagem aqui


o mapa está sendo usado como uma cópia superficial
TamusJRoyce

7

Outra solução poderia ser:

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

Você basicamente trabalha com os índices de array


2
Parece uma maneira estranha de fazer isso, mas a abordagem reduceRight também é estranha se você deseja acessar o índice além do elemento, não deseja realmente fazer uma redução, etc. No meu caso, este foi o solução mais limpa.
RealHandy de

1
Se você precisar fazer mais trabalho dentro do mapa, usar arr não [...] requer uma segunda cópia ou manipulação do array original. Esqueci o terceiro parâmetro. O que eu estava procurando!
TamusJRoyce,

6

Prefiro escrever a função mapReverse uma vez e depois usá-la. Além disso, não é necessário copiar o array.

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 Você passa o array para mapear Revers e na função você retorna o array invertido. No mapa cb você simplesmente pega os valores com o índice contando de 10 (comprimento) até 1 do array passado


Uma explicação por escrito sobre o que este código está fazendo pode ser útil.
Pro Q de

0

Aqui está minha solução TypeScript que é O (n) e mais eficiente do que as outras soluções, evitando uma execução na matriz duas vezes:

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

Em 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

Você pode fazer myArray.reverse () primeiro.

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

Essa seria a minha solução em geral, mas na configuração que estou usando o cartão de cima é colocado com o último índice. Acho que apenas uma indexação melhor poderia resolver o problema.
Robin Newhouse,

16
Apenas como uma observação, isso inverterá o array original no lugar, o que significa que alterará a ordem do array de forma destrutiva.
AdamCooper86

-2

Uma questão antiga, mas para novos visualizadores, esta é a melhor maneira de reverter a matriz usando o mapa

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

isso modifica a matriz original
TamusJRoyce,

talvez você quisesse dizer [...myArray].map((_, _, arr) => arr.pop());:?
Madeo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.