Tôi muốn lấy đầu vào như:Làm cách nào để tóm tắt mảng các số nguyên dưới dạng một dãy các dải ô?
[1,2,4,5,6,7,9,13]
và biến nó thành một cái gì đó như sau:
[[1,2],[4,7],[9,9],[13,13]]
Mỗi mảng tiểu đại diện cho một loạt các số nguyên.
Tôi muốn lấy đầu vào như:Làm cách nào để tóm tắt mảng các số nguyên dưới dạng một dãy các dải ô?
[1,2,4,5,6,7,9,13]
và biến nó thành một cái gì đó như sau:
[[1,2],[4,7],[9,9],[13,13]]
Mỗi mảng tiểu đại diện cho một loạt các số nguyên.
cách tiếp cận chức năng sử dụng Enumerable#chunk:
xs.enum_for(:chunk).with_index { |x, idx| x - idx }.map do |diff, group|
[group.first, group.last]
end
# => [[1, 2], [4, 7], [9, 9], [13, 13]]
Cách hoạt động: khi lập chỉ mục, các yếu tố liên tiếp trong mảng có cùng x - idx
, vì vậy chúng tôi sử dụng giá trị đó để đoạn (nhóm các mặt hàng liên tiếp) mảng đầu vào. Cuối cùng, chúng ta chỉ cần lấy các phần tử đầu tiên và cuối cùng của mỗi nhóm để xây dựng các cặp.
Điều này trông rất đẹp. Hoàn toàn quên về phương pháp đoạn mới. – cvshepherd
Và để thực hiện thêm một bước nữa, '.map {| min, max | min == max? min: min .. max} 'sẽ dẫn đến:' [1..2, 4..7, 9, 13] '. –
Hoặc thay đổi '[pairs.first [0], pairs.last [0]]' thành 'pairs.first [0] .. pairs.last [0]' để lấy các dải trong tất cả các vị trí: '[1. .2, 4..7, 9..9, 13..13] '. –
Một cách tiếp cận
def summarize(x)
x.inject([]) do |acc, value|
if acc.last && acc.last[1] + 1 == value
acc.last[1] = value
acc
else
acc << [value,value]
end
end
end
Tương tự như phương pháp Larsenal nhưng sử dụng bơm để quản lý những thứ nhàm chán.
Hmm, tốt, nó không phải tokland's kiệt tác, nhưng tôi nghĩ rằng nó có thể là một giải pháp đơn giản tốt ...
[1,2,4,5,6,7,9,13].inject([]) do |m, v|
if m.last.to_a.last == v.pred
m[-1][-1] = v
else
m << [v, v]
end
m
end
này là gần như trực tiếp từ tài liệu enumerable#slice_before phương pháp:
ar = [1,2,4,5,6,7,9,13]
prev = ar[0]
ar.slice_before{|e|prev,prev2 = e,prev; prev2.succ != e}.map{|a|a.first..a.last}
#=> [1..2, 4..7, 9..9, 13..13]
Điều này sẽ làm việc với các ký tự, ngày tháng, bất cứ điều gì với một phương pháp .succ
.
Một giải pháp dễ dàng hơn so với @tokland's very nice one đang sử dụng chunk_while
:
xs.chunk_while { |a, b| a + 1 == b }.map do |seq|
[seq.first, seq.last]
end
Note: chunk_while
đã được giới thiệu trong Ruby 2.3
Bạn có yêu cầu nếu có code để làm điều này chưa? Bạn đang yêu cầu bởi vì bạn đang cố gắng để cuộn của riêng bạn và gặp rắc rối khi thực hiện nó? – bobbymcr
Tôi đang lăn của riêng mình. Dường như luôn có những cách thú vị để thực hiện loại điều này trong Ruby. – Larsenal
Theo đó các điều kiện nào là phạm vi phải được xây dựng? – cvshepherd