2016-06-24 74 views
2

如果我有一個數組:array = ["ruby", "code", "library"]。如何將匹配的/ ^庫$ /元素移動到開頭。所以陣列看起來像這樣:array = [「library」,「ruby」,「code」]紅寶石排序陣列 - 移動匹配元素到開始

+0

雖然我認爲Sean的回答比較好,可以使用'array.sort {| str | str.match(/^library $ /)? 0:1}' –

回答

5

它可以通過多種方式完成。這是一個

array = ["ruby", "code", "library"] 
array.partition { |element| element.match /^library$/ }.flatten 
+1

[Enumerable#partition](http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-partition)可能會保留順序,但是文檔是靜音的。 –

2

只是出於好奇:

[:select, :reject].map do |m| 
    ["ruby", "code", "library"].public_send(m, &(/^library/.method(:=~))) 
end.reduce :| 
+0

這是一個相當有趣的方式去做。不錯的想法練習:) – Sean

+0

@Sean Yeah,這更多的是關於ruby-golf的笑話,而不是真正的代碼。但作爲一種練習,它很好。請修改,我更新了它。 – mudasobwa

+0

'reduce:|'讓我發笑。我們可以稱之爲「meh」運營商嗎? –

1
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保留該移動這些元素的順序和那些沒有移動。

0

三分一分。

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 

Th e最後一個:使用grep

array.grep(/library/) + array.grep(/^(?!library)/) 
+0

最後一個不會做你認爲它的作用。 '/ [^ library] /'會匹配任何包含'l','i','b'等字符的字符串。也許你的意思是'/ ^(?!library)/'? –

+0

@Jordan,我知道這和/ ^(?!庫)/會更好,我猜想,但事情是:它的作品,因爲它可以讓其他字符串,而不是「圖書館」 – peter

+0

當然,但它也會匹配'「lliibbrraarryy」'和''yrarbil「'。 –