Giả sử bạn có chính xác hai danh sách và họ là chính xác cùng độ dài, đây là một giải pháp ban đầu của Merlyn (Randal Schwartz), người gọi nó là phần châm Perlish:
sub zip2 {
my $p = @_/2;
return @_[ map { $_, $_ + $p } 0 .. $p - 1 ];
}
gì xảy ra ở đây là cho một Danh sách 10 phần tử, trước tiên, chúng tôi tìm thấy điểm pivot ở giữa, trong trường hợp này là 5 và lưu nó trong $p
. Sau đó chúng ta tạo một danh sách các chỉ số cho đến thời điểm đó, trong trường hợp này là 0 1 2 3 4. Tiếp theo chúng ta sử dụng map
để ghép mỗi chỉ mục với một chỉ mục khác ở cùng khoảng cách với điểm pivot khi chỉ mục đầu tiên là từ đầu, cho chúng tôi (trong trường hợp này) 0 5 1 6 2 7 3 8 4 9. Sau đó, chúng tôi lấy một lát từ @_
bằng cách sử dụng đó làm danh sách các chỉ mục. Điều này có nghĩa là nếu 'a', 'b', 'c', 1, 2, 3
được chuyển đến zip2
, nó sẽ trả về danh sách được sắp xếp lại thành 'a', 1, 'b', 2, 'c', 3
.
này có thể được viết bằng một biểu thức duy nhất dọc theo các đường ysth của như vậy:
sub zip2 { @_[map { $_, $_ + @_/2 } 0..(@_/2 - 1)] }
Cho dù bạn muốn sử dụng một trong hai biến thể phụ thuộc vào việc bạn có thể nhìn thấy mình nhớ cách họ làm việc, nhưng đối với tôi, đó là một tâm trí giãn nở.
Nguồn
2008-09-16 12:56:05
Mã zip của Haskell không phải là những gì bạn đang tìm kiếm: nó trả về danh sách các cặp tương ứng, không phải danh sách các phần tử xen kẽ. –
Bạn nói đúng; Danh sách Haskell chứa các phần tử nếu một loại duy nhất. Tôi đã không suy nghĩ khi tôi gọi Haskell ở đây. – asjo
Thường thì khi người ta nghĩ rằng họ muốn có một zip, nó là để tạo ra một băm từ hai danh sách. Trong trường hợp đó tốt hơn để sử dụng một lát băm. '@hash {@keys} = @ values'. Nếu đó không phải là trường hợp ở đây, thì xin lỗi vì tiếng ồn. –