Чи є спосіб використовувати map () на масиві в зворотному порядку за допомогою JavaScript?


96

Я хочу використовувати 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-індекс за індексом масиву. Я думаю, я міг би встановити z-індекс негативним.
Робін Ньюхаус,

Звучить як гарна ідея.
Джон

У примітці, чи ви насправді використовуєте масив, який mapповертається? В іншому випадку вам слід подумати forEach.
канон

1
Ви могли отримати доступ до зворотного елемента в зворотному виклику на карті:console.log(coll[coll.length - index - 1] + " ")
le_m

Відповіді:


149

Якщо ви не хочете повертати назад початковий масив, ви можете зробити його дрібну копію, а потім карту зворотного масиву,

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

У підсумку я просто використав негативний індекс, щоб вказати z-індекс, але, як я поставив питання, це найбільш правильно.
Робін Ньюхаус,

3
Навіщо нам .slice (0)? Чому не myArray.reverse () замість myArray.slice (0) .reverse ()? Схоже , відповідь на мій коментар тут: stackoverflow.com/questions/5024085 / ...
Haradzieniec

Haradzieniec - Це поєднується із подробицями того, як було сформовано оригінальне запитання, оскільки оригінальне впорядкування було потрібно для встановлення властивості css-індексу Z, але надруковано у зворотному порядку.
AdamCooper86,

Це slice(0)не потрібно, оскільки reverse()повертає новий масив і не змінює поточний масив. @ AdamCooper86, сподіваюся, ви це зміните.
Фахд Ліхідхеб

4
@FahdLihidheb ЗМІНЮЄ reverse()вихідний масив.
Ферус

20

Не мутуючи масив взагалі, ось однолінійне рішення O (n), яке я придумав:

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

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

додатково, 3-м аргументом map () є сам масив
Кнут,

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.