Есть ли способ использовать 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(...
АдамКупер86
источник
Я закончил тем, что просто использовал отрицательный индекс для указания 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]);
Tyborg
источник
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)

гость271314
источник
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 ]
edi9999
источник
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());:?
Мадео