2011-11-01 27 views
6

delete_at chỉ mất một chỉ mục duy nhất. Cách tốt để đạt được điều này bằng cách sử dụng các phương pháp tích hợp là gì? Không nhất thiết phải là một tập hợp, cũng có thể là một mảng các chỉ mục.Xóa nội dung của mảng dựa trên tập hợp các chỉ mục

arr = ["a", "b", "c"] 
set = Set.new [1, 2] 
arr.delete_at set 
# => arr = ["a"] 
+0

phải nhất thiết là một sửa đổi tại chỗ? – tokland

+0

Tôi lấy nó là bạn đang sử dụng kiểu Set trong 'Set.new' để đảm bảo tính duy nhất, thay vì chỉ sử dụng một mảng khác? – Mirv

Trả lời

12

One-liner:

arr.delete_if.with_index { |_, index| set.include? index } 
+0

Chỉ cần lưu ý, vì khó tìm kiếm ký hiệu gạch dưới '_' - đó là trình giữ chỗ thường được sử dụng nếu bạn chỉ cần bỏ qua chỉ mục. '_' là một biến hợp lệ, nhưng dòng mã không đi bất cứ thứ gì với nó. – Mirv

1

Hãy thử điều này:

arr.reject { |item| set.include? arr.index(item) } # => [a] 

Nó một chút xấu xí, tôi nghĩ;) Có lẽ ai đó đề nghị một giải pháp tốt hơn?

+0

Một giải pháp đơn giản cho vấn đề của tôi, trong khi những người khác thất bại! – dariush

4

Mở lại lớp Array và thêm phương thức mới cho việc này.

class Array 

    def delete_at_multi(arr) 
    arr = arr.sort.reverse # delete highest indexes first. 
    arr.each do |i| 
     self.delete_at i 
    end 
    self 
    end 

end 

arr = ["a", "b", "c"] 
set = [1, 2] 

arr.delete_at_multi(set) 

arr # => ["a"] 

Điều này tất nhiên có thể được viết thành phương pháp độc lập nếu bạn không muốn mở lại lớp học. Đảm bảo rằng các chỉ mục theo thứ tự ngược lại là rất quan trọng, nếu không bạn thay đổi vị trí của các phần tử sau này trong mảng được cho là sẽ bị xóa.

+0

+1, nhưng * delete_at_indices * sẽ là tên tốt hơn: nó giữ nguyên khả năng đọc của delete_at, nhưng vẫn rõ ràng là phải mất nhiều chỉ mục. Theo như khả năng đọc, bạn có thể nói "xóa ở 3" hoặc "xóa tại chỉ mục 3, 5 và 7" nhưng bạn sẽ không nói "xóa ở đa 3, 5 và 7". (Và tất nhiên, đối với những người không hiểu về việc sử dụng từ "chỉ mục", có thể có bí danh * delete_at_indexes *;) – iconoclast

0

cách tiếp cận chức năng:

class Array 
    def except_values_at(*indexes) 
    ([-1] + indexes + [self.size]).sort.each_cons(2).flat_map do |idx1, idx2| 
     self[idx1+1...idx2] || [] 
    end 
    end 
end 

>> ["a", "b", "c", "d", "e"].except_values_at(1, 3) 
=> ["a", "c", "e"] 
Các vấn đề liên quan