Ruby's Array # shift làm gì?


88

Tôi đang gặp khó khăn khi hiểu các phương thức shift và unshift của lớp Array làm gì trong Ruby. Ai đó có thể giúp tôi hiểu họ làm gì không?


171
Khi bạn biết được điều đó shift/unshiftgiống như push/popở đầu kia của mảng, bạn có thể nhẩm chữ 'f' khỏi tên của các phương thức để nhớ phương thức nào 'kết xuất' và phương thức nào 'chèn' chúng. :)
Phrogz

1
Cảm ơn điều đó thực sự giúp lol.
agentbanks217

Một trong những nhận xét tốt nhất bao giờ hết! Cảm ơn bạn rất nhiều :)
tvdeyen

18
@Phrogz Trên thực tế, hệ tiêu hóa của động vật có xương sống được mô hình hóa dưới dạng hàng đợi tốt hơn là dạng ngăn xếp.
Jian

8
@Jian :) Đúng: pushnó vào đầu, và shiftnó ra đầu kia.
Phrogz

Câu trả lời:


98

Nhìn vào Tài liệu Ruby

Array.shift xóa phần tử đầu tiên khỏi mảng và trả về nó

a = [1,2,3] 
puts a.shift
 => 1 
puts a
 => [2, 3] 

Unshift thêm giá trị đã cho vào trước mảng, di chuyển tất cả các phần tử khác lên trên một

a=%w[b c d]
 => ["b", "c", "d"] 
a.unshift("a")
 => ["a", "b", "c", "d"] 

8
Về cơ bản bạn có thể nghĩ đến sự thay đổi và unshift như là hoạt động trên một hàng đợi FIFO
Jaco Pretorius

@JacoPretorius Hả? shiftunshifthoạt động như một ngăn xếp FILO, pushshiftsẽ hoạt động như một hàng đợi FIFO, trừ khi tôi nhầm lẫn về điều gì đó.
Greg Schmit

@GregSchmit Ah, bạn nói đúng. Hay thực ra, một hàng đợi LIFO, phải không?
Jaco Pretorius

@JacoPretorius Vâng, tôi nghĩ LIFO == FILO (đầu tiên ra sau ngụ ý rằng cái cuối cùng phải xuất hiện trước nếu mô hình được giữ nguyên).
Greg Schmit

@JacoPretorius Cả LIFO và FILO đều có nghĩa là "hoạt động như một ngăn xếp".
Greg Schmit

52

shiftunshifthoạt động theo cách tương tự như poppush: chúng có nghĩa là sử dụng các mảng làm ngăn xếp mà bạn có thể nối và xóa các phần tử (thường là một phần tử mỗi lần). Sự khác biệt chỉ là shiftunshiftthêm / bớt các phần tử ở đầu một Array, thực sự thay đổi tất cả các phần tử khác, trong khi poppushthêm / bớt các phần tử ở cuối Array, do đó vẫn giữ nguyên các chỉ số của các phần tử khác.

Ví dụ:

                      # Spacing for clarity:
a = [2, 4, 8]    # a =>       [2, 4, 8]
a.push(16, 32)   # a =>       [2, 4, 8, 16, 32]
a.unshift(0, 1)  # a => [0, 1, 2, 4, 8, 16, 32]
a.shift          # a =>    [1, 2, 4, 8, 16, 32]
a.pop            # a =>    [1, 2, 4, 8, 16]

Nếu bạn chỉnh sửa câu trả lời của mình để tóm tắt chủ đề mipadi, tôi rất vui được ủng hộ.
Steven Sudit

Mát mẻ. Ngoài ra, tôi không am hiểu nhiều về Ruby, nhưng nếu nó chạy trên JVM thì tôi hy vọng rằng push / pop sẽ nhanh hơn, vì nó không phải di chuyển tất cả các yếu tố đó.
Steven Sudit

Ủng hộ cho sự tương tự ngăn xếp, nhưng hãy nghĩ đến cả đường ống. Vì chúng ta được coi là lập trình viên, chúng ta cũng nên nghĩ rằng shift là sự dịch chuyển sang trái và không dịch chuyển là sự dịch chuyển sang phải trên một mảng ngang trái sang phải.
mckenzm

8

Nó lấy phần tử đầu tiên, xóa nó khỏi mảng và trả về phần tử đã xóa. Về cơ bản nó là một cách để coi một mảng giống như một ngăn xếp: shiftlà pop, unshiftlà push.


8
Well shift và unshift tương tự như pop và push, ngoại trừ chúng thêm và xóa nội dung từ đầu một mảng, thay vì từ cuối.
Alberto Santini

2
Câu trả lời này chính xác là ở mức trừu tượng chính xác.
Steven Sudit

@Alberto: Hay nói cách khác, họ coi bình phong là hàng đầu. Không có yêu cầu đối với nó là khác.
Steven Sudit

5
Tôi chỉ chỉ ra rằng, vì poppushcũng là Arrayphương pháp, không nên nhầm lẫn. :-)
Alberto Santini

3
@Alberto: Đó thực sự là một điểm tốt. Các phương thức shift / unshift sử dụng front as top trong khi các phương thức push / pop sử dụng end là top. Cả hai đều coi mảng như một ngăn xếp, chỉ khác nhau về đầu cuối mà chúng sử dụng.
Steven Sudit

2

Nếu bạn có thể coi mảng giống như một hàng đợi các giá trị cần được xử lý, thì bạn có thể lấy giá trị (phía trước) tiếp theo và "dịch chuyển" giá trị khác qua để chiếm không gian có sẵn. unshift đặt các giá trị trở lại - có thể bạn chưa sẵn sàng xử lý một số trong số chúng hoặc sẽ để một số mã sau này xử lý chúng.


1

Nó trả về phần tử đầu tiên của mảng và xóa nó khỏi mảng, dịch chuyển các phần tử về một chỗ.

Vì vậy, chuyển dịch [1,2,3,4,5]

trả về 1và đặt mảng là [2,3,4,5].

Thêm ở đây .

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.