7

私はRubyを学んでいて、配列と範囲についていくつかのことを学びました。スライスについて何かに遭遇しました。一見それは理にかなっていますが、深く見ると少し混乱します。

IRBによると、これ(2..-1).to_aは空の配列であり、範囲内に値がないことを意味します。
しかし、で同じ範囲を使用すると、空の配列ではなく[:a, :b, :c, :d, :e][2..-1]戻ります。[:c, :d, :e]

さて、-1は配列の最後の要素を表していることを知っているので、選択されたものが実行されたことは理にかなっています。しかし、範囲自体が空になる場合、どのように何かを選択するのでしょうか。

4

3 に答える 3

11

これは魅力的な質問です。答えは、配列をスライスするときに検査されるのは範囲の個々の要素ではなく、firstandlast要素であるということです。具体的には:

>> (2..-1).to_a
=> []
>> (2..-1).first
=> 2
>> (2..-1).last
=> -1

[2]したがって、この例は、配列を要素から要素にスライスするため、機能し[-1]ます。

これについて一貫した考え方が必要な場合は、との間で(2..-1).to_a見つかった整数(その中にはありません)を出力することを検討してください。ただし、これはインデックスからインデックスへの変換を意味します2-1[2..-1]2 -1

(出典:array.cおよびrange.cRubyソース内。)

そして、複雑なボーナス部分:あなたが考えていた意味を得るために、あなたは使うことができます

>> [:a, :b, :c, :d, :e].values_at *(2..-1).to_a
=> []
于 2010-10-01T09:06:30.197 に答える
3

スライス操作では、範囲Range自体は表示されず、エンドポイントの値(この場合は2と)のみが表示され-1ます。特別な意味(つまり、リストの最後のアイテム)があるため-1、インデックスのアイテムから2リストの最後まですべてを返します。Rangeここではなく、2つの数値(2つのエンドポイントを表す)を渡す便利な方法と考えてください。

于 2010-10-01T09:06:25.693 に答える
1

このArray#[]メソッドは、範囲を範囲として使用しません(つまり、範囲などを呼び出しませんinclude?)。それはそれから2つの数字を取り出して、それが排他的であるかどうかをチェックするだけです。

あなたはそれがいくぶんこのように見えることを想像することができます(実際はRuby[]ではなくCで実装されており、もちろん範囲以外の引数も処理します):

def [](range)
  start = range.begin
  length = range.end - start
  length -= 1 if range.exclude_end?
  slice(start, length)
end
于 2010-10-01T09:07:34.640 に答える