4

最初は、次のようなことをするつもりでした。

arr = [[1,2],[3,4]]
new_arr = 
arr.map do |sub_arr|
    sub_arr.map do |x|
        x+1
    end
end

p new_arr

出力:

[[2,3],[4,5]]

しかし、それから私は列挙子を「連鎖」させることによってそれを短くしようとしました:

arr.map.map{|x| x+1}

その後、エラーが発生しますto_ary method missing

私はそれをデバッグしました

arr.each.each{|x| p x}

出力:

[1,2]
[3,4]

、これは元の配列であり、一度だけ検出されます。

2つのマップ/各列挙子をチェーンして、列挙子を2つ(またはそれ以上)のレベルにするにはどうすればよいですか?またはそれはブロック内にある必要がありますか?


アップデート:

いくつかの検索の後、チェーンobj.Enumerator.Enumerator.Enumerator...はobjを1回だけ列挙し、1レベルの深さしか列挙しないようです。さらに深く進むには、ブロックが必要です。文字列をブロックに変換する単純なコード(Proc / Lambda;シンボルからブロックに似ていますが、より多くの使用法;より機能的な構文に似ています)を作成して、ブロックが回避されるようにしました。誰かが似たようなコードを持っていますString#to_procが、私はそれを見つけることができませんでした、そしてその中のx,yものは私の好みにアピールしません。私が使う$0,$1,$2,...

サンプルコード(前の例は次のように記述されます):

arr = [[1,2],[3,4]]
new_arr = arr.map(&'[$0+1,$1+1]')
p new_arr

後で元のコードをgithubにプッシュします。私が本当に先延ばしにしているので、その前にそれを見たい場合は、チャットを使用して私に連絡することができます:)

4

5 に答える 5

3

再帰の仕事のように聞こえます:

def zipper(args)
  args[0].respond_to?(:each) ? args.map{|a| zipper(a)} : args.map{|i| i+1}
end

zipper([[1,2],[3,4]])
# => [[2, 3], [4, 5]]

zipper([[[1,2],[3,4]],[5,6]])
# => [[[2, 3], [4, 5]], [6, 7]]
于 2012-04-14T07:20:30.247 に答える
3

おそらくmap、葉だけに適用したいものが必要です:

module Enumerable
  def nested_map &block
    map{|e|
      case e
      when Enumerable
        e.nested_map(&block)
      else
        block.call(e)
      end
    }
  end
end

p [[1,2], [3,4]].nested_map(&:succ)
#=> [[2, 3], [4, 5]]

または、ネストされた構造の第5レベルにmapのみ適用されます。n

module Enumerable
  def deep_map level, &block
    if level == 0
      map(&block)
    else
      map{|e| e.deep_map(level - 1, &block)}
    end
  end
end

p [[1,2], [3,4]].deep_map(1, &:succ)
#=> [[2, 3], [4, 5]]
于 2012-04-14T08:20:08.313 に答える
2
arr.map {|x| x.map(&:succ)} #=> [[2, 3], [4, 5]]
于 2012-08-14T00:23:19.410 に答える
0

一度だけ書くことでそれをするためにx+1、あなたはそれをブロックに入れる必要があります。それ以外の場合は、次のことができます。

new_arr = arr.map {| x、y | [x + 1、y + 1]}

または、主張する場合は、次のことができます。

new_arr = arr.flatten(1).map {| x | x + 1} .each_slice(2).to_a

于 2012-04-14T05:03:58.977 に答える
0

個人的には、以下の2つのオプションのいずれかのように記述して、それで完了します。

arr.map { |a| a.map(&:next) } 
#=> [[2, 3], [4, 5]]
arr.map { |x, y| [x.next, y.next] } 
#=> [[2, 3], [4, 5]]
于 2012-04-14T10:57:20.267 に答える