[英]ruby sorting array - moving matched elements to the beginning
如果我有一個數組: array = ["ruby", "code", "library"]
。 如何將匹配的/ ^ library $ / elements移動到開頭。 所以數組看起來像這樣:array = [“library”,“ruby”,“code”]
它可以通過多種方式完成。 這是一
array = ["ruby", "code", "library"]
array.partition { |element| element.match /^library$/ }.flatten
只是出於好奇:
[:select, :reject].map do |m|
["ruby", "code", "library"].public_send(m, &(/^library/.method(:=~)))
end.reduce :|
def move_to_front(arr, pattern)
mi = matching_indices(arr, pattern)
return arr unless mi
a = arr.dup
mi.reverse_each.with_object([]) { |i,b| b.unshift(a.delete_at(i)) }.concat(a)
end
def matching_indices(arr, pattern)
arr.each_index.select do |i|
case pattern
when Regexp then arr[i] =~ pattern
when Proc then pattern[arr[i]]
else (arr[i] == pattern)
end
end
end
move_to_front ["ruby", "code", "library"], /\Alibrary\z/
#=> ["library", "ruby", "code"]
move_to_front ["ruby", "library", "code", "library"], "library"
#=> ["library", "library", "ruby", "code"]
move_to_front ["ruby", "libraries", "code", "library"], /librar(?:ies|y)/
#=> ["libraries", "library", "ruby", "code"]
move_to_front ["ruby", "libraries", "code", "library"], /\Alibrar/
#=> ["libraries", "library", "ruby", "code"]
move_to_front ["ruby", "libraries", "code", "library"],
->(str) { str =~ /librar(?:ies|y)/ }
#=> ["libraries", "library", "ruby", "code"]
move_to_front ("1".."9").to_a, /[13579]/
#=> ["1", "3", "5", "7", "9", "2", "4", "6", "8"]
move_to_front ("1".."9").to_a, ->(n) { n.to_i.odd? }
#=> ["1", "3", "5", "7", "9", "2", "4", "6", "8"]
move_to_front ("1".."9").to_a, ->(n) { false }
#=> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
move_to_front ("1".."9").to_a, ->(n) { true }
#=> ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
注意:
matching_indices ["ruby", "libraries", "code", "library"], /librar(?:ies|y)/
#=> [1, 3]
方法move_to_front
保留移動的元素和未移動的元素的順序。
三分錢一分。
array.inject([]){|a,e| e[/^library/] ? a.unshift(e) : a<<e}
和
array & ["library"] | array
如果數組包含多次搜索元素,則變為
array.find_all{ |e| e[/^library/] } + array.reject{ |e| e[/^library/] }
如果你討厭兩次使用數組變量,它也可以這樣
[array].map{|a| a & ["library"] | a}.flatten
最后一個:使用grep
array.grep(/library/) + array.grep( /^(?!library)/)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.