有没有办法使用JavaScript以相反的顺序在数组上使用map()?


93

我想map()在JavaScript数组上使用该函数,但是我希望它以相反的顺序运行。

原因是,我正在Meteor项目中渲染堆叠的React组件,并希望顶层元素首先渲染,而其余部分则在下面加载图像。

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
佳能2016年

1
您可以在地图回调中访问反向元素:console.log(coll[coll.length - index - 1] + " ")
le_m

Answers:


145

如果您不想反转原始数组,可以对其进行浅表复制,然后映射反转数组,

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

我最终只是使用负索引来指定z-index,但是按照我构架问题的方式,这是最正确的。
罗宾·纽豪斯

3
为什么我们需要.slice(0)?为什么不使用myArray.reverse()代替myArray.slice(0).reverse()?看来我的评论答案在这里:stackoverflow.com/questions/5024085/…–
Haradzieniec

Haradzieniec-它与原始问题的构成方式特别相关,因为需要原始顺序来设置Z-index css属性,但需要反向打印。
AdamCooper86

slice(0),因为不需要reverse()返回一个新的数组,不改变当前的阵列。@ AdamCooper86我希望你能改变它。
Fahd Lihidheb

4
@FahdLihidhebreverse()确实修改了原始数组。
Ferus

20

根本不改变数组,这是我想出的一线O(n)解决方案:

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

val在这里没有使用,所以我不认为这是OP想要的吗?(仍然是一个很好的解决方案)
Paul Razvan Berg,

此外,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)


注意(如果您仍然想执行还原)-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
这似乎是一种奇怪的方法,但是,如果您除了要访问元素之外还想要访问索引,而又不想真正执行reduce的话,那么reduceRight方法也很奇怪。最干净的解决方案。
RealHandy

1
如果您需要在地图内做进一步的工作,则使用arr [...]不需要第二个副本或操作原始数组。忘记了第三个参数。我在找什么!
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));

我将数组传递给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 '16

-2

一个古老的问题,但对于新观众来说,这是使用map反转数组的最佳方法

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

这修改了原始数组
TamusJRoyce

也许你的意思:[...myArray].map((_, _, arr) => arr.pop());
Madeo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.