2016-06-24 13 views
2

配列がある場合:array = ["ruby", "code", "library"]。一致する/ ^ライブラリ$ /要素を先頭に移動するにはどうすればよいですか?配列は次のようになります:array = ["library"、 "ruby"、 "code"]ruby​​ソート配列 - 一致した要素を先頭に移動

+0

私はSeanの答えが良いと思いますが、 'array.sort {| str | str.match(/^library $ /)? 0:1} ' –

答えて

5

これはいくつかの方法で実行できます。これは単なる好奇心のうち1

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-partition)は注文を保存するかもしれませんが、ドキュメントはそれを無視しています。 –

2

です:

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

これはかなり興味深い方法です。ニースの思考の練習:) – Sean

+0

@Seanええ、これはルビーのゴルフのジョークについて、実際のコードよりもです。しかし、運動としては大丈夫です。改訂して、私はそれを更新しました。 – 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

3セント1セント。あなたはそれをすることもでき、この

のように二回配列変数を使用することを嫌う場合

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最後の1つ:grepを使用して

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

最後のものは、あなたが思っていることをしません。 '/ [^ library] /'は、 'l'、' i'、 'b'など以外の文字を含む文字列にマッチします。おそらくあなたは'/^(?! library)/ 'を意味していますか? –

+0

@Jordan、私はそれを知っていて、/ ^(?! library)/もっと良いと思うかもしれませんが、それは他の文字列と "library"を渡すことができるからです。 – peter

+0

もちろん、 '' lliibbrraarryy' 'と' 'yrarbil''を使用します。 –

関連する問題