Có cách nào để sử dụng map () trên một mảng theo thứ tự ngược lại với javascript không?


94

Tôi muốn sử dụng map()hàm trên một mảng javascript, nhưng tôi muốn nó hoạt động theo thứ tự ngược lại.

Lý do là, tôi đang kết xuất các thành phần React xếp chồng lên nhau trong một dự án Meteor và muốn phần tử cấp cao nhất hiển thị trước trong khi phần còn lại tải hình ảnh bên dưới.

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

in ra a b c d enhưng tôi ước có một mapReverse () được ine d c b a

Bất kỳ đề xuất?


2
Tại sao bạn không reversemảng?
John

2
Để sắp xếp thứ tự các phần tử, tôi đặt chỉ số z bằng chỉ số mảng. Tôi cho rằng tôi có thể đặt chỉ số z là âm.
Robin Newhouse

Nghe có vẻ như một ý tưởng tốt.
John

Một lưu ý nhỏ, bạn có thực sự sử dụng mảng maptrả về không? Nếu không, bạn nên xem xét forEach.
canon

1
Bạn có thể truy cập phần tử đảo ngược trong lệnh gọi lại của bản đồ:console.log(coll[coll.length - index - 1] + " ")
le_m

Câu trả lời:


147

Nếu bạn không muốn đảo ngược mảng ban đầu, bạn có thể tạo một bản sao cạn của nó sau đó lập bản đồ của mảng đã đảo ngược,

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

Tôi đã kết thúc chỉ sử dụng chỉ số phủ định để chỉ định chỉ số z, nhưng theo cách tôi đóng khung câu hỏi thì đây là câu hỏi đúng nhất.
Robin Newhouse

3
Tại sao chúng ta cần .slice (0)? Tại sao không phải myArray.reverse () thay vì myArray.slice (0) .reverse ()? Có vẻ như câu trả lời cho nhận xét của tôi là ở đây: stackoverflow.com/questions/5024085/…
Haradzieniec

Haradzieniec - Nó đi kèm với các chi tiết về cách câu hỏi ban đầu được đóng khung, trong đó thứ tự ban đầu là cần thiết để thiết lập thuộc tính Z-index css, nhưng được in ngược lại.
AdamCooper86

Các slice(0)không cần thiết như reverse()trả về một mảng mới và không sửa đổi các mảng hiện hành. @ AdamCooper86 tôi hy vọng bạn thay đổi điều đó.
Fahd Lihidheb

4
@FahdLihidheb reverse()KHÔNG sửa đổi mảng ban đầu.
Ferus

20

Không làm thay đổi mảng nào cả, đây là một giải pháp O (n) một lớp lót mà tôi đã đưa ra:

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

valkhông được sử dụng ở đây, vì vậy tôi không nghĩ đây là những gì OP đang tìm kiếm? (nó vẫn là một giải pháp tốt)
Paul Razvan Berg

ngoài ra, đối số thứ 3 của map () là chính mảng
Knut

19

Bạn có thể dùng 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 (nếu bạn đang muốn thực hiện thao tác giảm bớt) - MDN: Phương thức ReduceRight () áp dụng một hàm đối với bộ tích lũy và mỗi giá trị của mảng (từ phải sang trái) để giảm nó thành một giá trị duy nhất.
TamusJRoyce

8

Với chức năng gọi lại được đặt tên

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

Viết tắt (không có hàm gọi lại được đặt tên) - Cú pháp mũi tên, ES6

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

Đây là kết quả

nhập mô tả hình ảnh ở đây


bản đồ đang được sử dụng như một bản sao cạn
TamusJRoyce

7

Một giải pháp khác có thể là:

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

Về cơ bản, bạn làm việc với các chỉ mục mảng


2
Đây có vẻ là một cách kỳ lạ để thực hiện, nhưng cách tiếp cận ReduceRight cũng khá kỳ quặc nếu bạn muốn truy cập vào chỉ mục ngoài phần tử, không thực sự muốn giảm, v.v. Trong trường hợp của tôi, đây là giải pháp sạch nhất.
RealHandy

1
Nếu bạn cần thực hiện thêm công việc bên trong bản đồ, sử dụng arr [...] không yêu cầu bản sao thứ hai hoặc thao tác với mảng ban đầu. Quên về tham số thứ 3. Những gì tôi đang tìm kiếm!
TamusJRoyce

6

Tôi thích viết hàm mapReverse một lần, sau đó sử dụng nó. Ngoài ra, điều này không cần phải sao chép mảng.

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 Bạn chuyển mảng để ánh xạ Revers và trong hàm, bạn trả về mảng đã đảo ngược. Trong bản đồ cb, bạn chỉ cần lấy các giá trị có chỉ số đếm từ 10 (độ dài) xuống 1 từ mảng đã truyền


Một lời giải thích bằng văn bản về những gì mã này đang làm có thể hữu ích.
Pro Q

0

Đây là giải pháp TypeScript của tôi vừa là O (n) vừa hiệu quả hơn các giải pháp khác bằng cách ngăn việc chạy qua mảng hai lần:

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

Trong 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

Bạn có thể thực hiện myArray.reverse () trước.

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

Đó sẽ là giải pháp của tôi nói chung, nhưng trong thiết lập tôi đang sử dụng thẻ trên cùng được đặt với chỉ mục cuối cùng. Tôi đoán chỉ một số lập chỉ mục tốt hơn có thể giải quyết vấn đề.
Robin Newhouse

16
Cũng giống như một lưu ý, điều này sẽ đảo ngược mảng ban đầu tại chỗ, có nghĩa là nó sẽ thay đổi thứ tự của mảng một cách triệt để.
AdamCooper86

-2

Một câu hỏi cũ nhưng đối với những người mới xem, đây là cách tốt nhất để đảo ngược mảng bằng cách sử dụng bản đồ

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

điều này sửa đổi mảng ban đầu
TamusJRoyce

có thể ý bạn là [...myArray].map((_, _, arr) => arr.pop());:?
Madeo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.