3

どうすればこれを実装できますか?私の解決策は非常に汚いと思います、そして私はそれをもっと良くしたいと思います。Rubyでこれを行う簡単な方法があると思いますが、思い出せません。Railsで使いたいので、Railsが似たようなものを提供していれば大丈夫です。使用法は次のようになります。

fruits = ['banana', 'strawberry', 'kiwi', 'orange', 'grapefruit', 'lemon', 'melon']

# odd_fruits should contain all elements with odd indices (index % 2 == 0)
odd_fruits = array_mod(fruits, :mod => 2, :offset => 0)

# even_fruits should contain all elements with even indices (index % 2 == 1)
even_fruits = array_mod(fruits, :mod => 2, :offset => 1)

puts odd_fruits
  banana
  kiwi
  grapefruit
  melon

puts even_fruits
  strawberry
  orange
  lemon

******* 編集 *******

知りたい人のために、それは私が最終的にしたことです:

Railsプロジェクトで、config/initializers/columnize.rb次のような新しいファイルを作成しました。

class Array
  def columnize args = { :columns => 1, :offset => 0 }
    column = []
    self.each_index do |i|
      column << self[i] if i % args[:columns] == args[:offset]
    end
    column
  end
end

Railsは、Railsがロードされた直後に、これらのファイルを自動的にロードします。私はまた、メソッドに引数を提供するための手ごわい方法を使用しました。これは、より読みやすいコードの目的に役立つと思います。私は読みやすいコードフェチです:)コアクラス「配列」を拡張しました。プロジェクト内のすべての配列で次のようなことができます。

>> arr = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]

>> arr.columnize :columns => 2, :offset => 0
=> [1, 3, 5, 7]
>> arr.columnize :columns => 2, :offset => 1
=> [2, 4, 6, 8]

>> arr.columnize :columns => 3, :offset => 0
=> [1, 4, 7]
>> arr.columnize :columns => 3, :offset => 1
=> [2, 5, 8]
>> arr.columnize :columns => 3, :offset => 2
=> [3, 6]

これを使用して、データベースのエントリをビューのさまざまな列に表示します。私が気に入っているのは、nilオブジェクトをビューに渡すとレールが文句を言うので、コンパクトなメソッドなどを呼び出す必要がないことです。今ではうまくいきます。また、JSにすべてを任せることも考えましたが、960グリッドシステム(http://960.gs)を使用して、この方法の方が気に入っています。

4

8 に答える 8

5
fruits = ["a","b","c","d"]
even = []
x = 2 
fruits.each_index{|index|
    even << fruits[index] if index % x == 0
}
odds = fruits - even
p fruits
p even
p odds



["a", "b", "c", "d"]
["a", "c"]
["b", "d"]
于 2009-12-10T17:05:00.540 に答える
3

私が考えることができる最も簡単な方法はこれです:

fruits = ["a","b","c","d"]
evens = fruits.select {|x| fruits.index(x) % 2 == 0}
odds = fruits - evens

select_with_index配列がインデックスを検索できる場合は、混乱する必要はありません。このメソッドの欠点は、同じ値の「fruits」に複数のエントリがある場合だと思います(このindexメソッドは最初に一致するエントリのインデックスのみを返します)。

于 2009-12-10T18:34:27.963 に答える
3
def array_mod(arr, mod, offset = 0)
  arr.shift(offset)
  out_arr = []

  arr.each_with_index do |val, idx|
    out_arr << val if idx % mod == 0
  end

  out_arr
end

使用法:

>> fruits = ['banana', 'strawberry', 'kiwi', 'orange', 'grapefruit', 'lemon', 'melon']

>> odd_fruits = array_mod(fruits, 2)
=> ["banana", "kiwi", "grapefruit", "melon"]

>> even_fruits = array_mod(fruits, 2, 1)
=> ["strawberry", "orange", "lemon"]

>> even_odder_fruits = array_mod(fruits, 3, 2)
=> ["kiwi", "lemon"]
于 2009-12-10T16:58:05.683 に答える
3

あなたが欲しいものは:

even_fruits  = fruits.select_with_index { |v,i| i % 2 == 0) }
odd_fruits = fruits - even_fruits

残念ながらEnumerable#select_with_index標準としては存在しませんが、何人かの人々がEnumerableそのような方法で拡張しました。

http://snippets.dzone.com/posts/show/3746 http://webget.com/gems/webget_ruby_ramp/doc/Enumerable.html#M000058

于 2009-12-10T17:08:04.170 に答える
2

コア機能のみを使用したソリューション:

(0...((fruits.size+1-offset)/mod)).map {|i| fruits[i*mod+offset]}
于 2009-12-10T18:42:59.553 に答える
1

Railsは、「in_groups_of」メソッドを提供するArrayのActiveSupport拡張機能を提供します。それは私が通常このようなものに使用するものです。それはあなたがこれをすることを可能にします:

均等な果物を引っ張る(最後にニルを引っ張るためにコンパクトにすることを忘れないでください):

fruits = ['banana', 'strawberry', 'kiwi', 'orange', 'grapefruit', 'lemon', 'melon']
fruits.in_groups_of(2).collect{|g| g[1]}.compact
=> ["strawberry", "orange", "lemon"]

奇妙な果物を引っ張る:

fruits.in_groups_of(2).collect{|g| g[0]}.compact
=> ["banana", "kiwi", "grapefruit", "melon"]

3つおきの果物を手に入れるには、次を使用できます。

fruits.in_groups_of(3).collect{|g| g[0]}.compact
=> ["banana", "orange", "melon"]
于 2009-12-10T17:44:53.330 に答える
0

機能的な方法

#fruits = [...]
even = []
odd = []

fruits.inject(true ){|_is_even, _el| even << _el if _is_even; !_is_even}
fruits.inject(false){|_is_odd,  _el| odd  << _el if _is_odd;  !_is_odd }
于 2009-12-10T19:35:38.887 に答える
0

これは、#enum_forを使用したソリューションです。これにより、#eachの「代わりに」使用するメソッドを指定できます。

require 'enumerator'
mod = 2
[1, 2, 3, 4].enum_for(:each_with_index).select do |item, index| 
  index % mod == 0 
end.map { |item, index| item }
# => [1, 2]
于 2009-12-10T19:39:53.277 に答える