Есть ли способ использовать map () в массиве в обратном порядке с помощью javascript?


95

Я хочу использовать эту map()функцию для массива javascript, но хочу, чтобы она работала в обратном порядке.

Причина в том, что я рендеринг составных компонентов React в проекте Meteor и хотел бы, чтобы элемент верхнего уровня отображался первым, а остальные загружали изображения ниже.

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

распечатывает, a b c d eно мне жаль, что не было mapReverse (), который напечаталe d c b a

Какие-либо предложения?


2
Почему бы вам не reverseмассив?
Джон

2
Чтобы упорядочить элементы, я устанавливаю z-index по индексу массива. Я полагаю, я мог бы установить z-index отрицательным.
Робин Ньюхаус

Звучит как хорошая идея.
Джон

Кстати, вы действительно используете mapвозвращаемый массив ? В противном случае вам следует подумать forEach.
canon

1
Вы можете получить доступ к обратному элементу в обратном console.log(coll[coll.length - index - 1] + " ")
вызове

Ответы:


148

Если вы не хотите переворачивать исходный массив, вы можете сделать его неглубокую копию, а затем отобразить обратный массив,

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

Я закончил тем, что просто использовал отрицательный индекс для указания z-индекса, но в том, как я сформулировал вопрос, это наиболее правильный.
Робин Ньюхаус

3
Зачем нам .slice (0)? Почему не myArray.reverse () вместо myArray.slice (0) .reverse ()? Похоже, ответ на мой комментарий здесь: stackoverflow.com/questions/5024085/…
Haradzieniec

Haradzieniec - это касается деталей того, как был сформулирован исходный вопрос, в том смысле, что исходный порядок был необходим для установки свойства Z-index css, но напечатан в обратном порядке.
AdamCooper86

slice(0)Не нужен , поскольку reverse()возвращает новый массив и не изменяет текущий массив. @ AdamCooper86, надеюсь, ты это изменишь.
Фахд Лихидхеб

4
@FahdLihidheb reverse()ДЕЙСТВИТЕЛЬНО изменяет исходный массив.
Ферус

20

Не изменяя массив вообще, вот однострочное решение O (n), которое я придумал:

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

valздесь не используется, поэтому я не думаю, что это то, что искал OP? (это все еще хорошее решение)
Пол Разван Берг

кроме того, третий аргумент map () - это сам массив
Knut

19

Ты можешь использовать 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 (если вы все равно хотите выполнить сокращение) - MDN: метод reduceRight () применяет функцию к аккумулятору и каждому значению массива (справа налево), чтобы уменьшить его до одного значения.
TamusJRoyce

8

С именованной функцией обратного вызова

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

Сокращение (без именованной функции обратного вызова) - синтаксис стрелки, ES6

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

Вот результат

введите описание изображения здесь


карта используется как мелкая копия
TamusJRoyce

7

Другим решением может быть:

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

Вы в основном работаете с индексами массива


2
Это кажется странным, но подход reduceRight также странен, если вы хотите получить доступ к индексу в дополнение к элементу, на самом деле не хотите сокращать и т. Д. В моем случае это был чистейшее решение.
RealHandy

1
Если вам нужно проделать дальнейшую работу внутри карты, использование arr [...] не требует второй копии или манипулирования исходным массивом. Забыл про 3-й параметр. То, что я искал!
TamusJRoyce

6

Я предпочитаю написать функцию mapReverse один раз, а затем использовать ее. Также не нужно копировать массив.

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 Вы передаете массив в карту Revers, а в функции возвращаете обратный массив. На карте cb вы просто берете значения с индексом от 10 (длина) до 1 из переданного массива


Письменное объяснение того, что делает этот код, может быть полезным.
Pro Q

0

Вот мое решение TypeScript, которое одновременно O (n) и более эффективно, чем другие решения, за счет предотвращения двойного прохода через массив:

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

В 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

Сначала вы можете выполнить myArray.reverse ().

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

Это было бы моим решением в целом, но в настройке, которую я использую, верхняя карта размещается с последним индексом. Думаю, проблему может решить только лучшая индексация.
Робин Ньюхаус

16
Как примечание, это изменит исходный массив на место, что означает, что он изменит порядок массива деструктивно.
AdamCooper86

-2

Старый вопрос, но для новых зрителей это лучший способ перевернуть массив с помощью карты

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

это изменяет исходный массив
TamusJRoyce

может ты имел ввиду [...myArray].map((_, _, arr) => arr.pop());:?
Мадео
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.