2011-01-08 11 views
4

私は知らない言語でコードスニペットを私に残してしまって、それを維持しなければならないという不快な立場にいます。私は自分自身にRubyを導入していませんが、その一部は非常にシンプルですが、それでもあなたの説明を聞きたいと思います。 は、ここに行く:Rubyコードスニペットを説明する

words = File.open("lengths.txt") {|f| f.read }.split # read all lines of a file in 'words'? 

values = Array.new(0) 
words.each { |value| values << value.to_i } # looked this one up, it's supposed to convert to an array of integers, right? 
values.sort! 
values.uniq! 

diffs = Array.new(0) # this looks unused, unless I'm missing something obvious 
sum = 0 
s = 0 # another unused variable 
# this looks like it's computing the sum of differences between successive 
# elements, but that sum also remains unused, or does it? 
values.each_index { |index| if index.to_i < values.length-1 then sum += values.at(index.to_i + 1) - values.at(index.to_i) end } # could you also explain the syntax here? 
puts "delta has the value of\n" 

# this will eventually print the minimum of the original values divided by 2 
puts values.at(0)/2 

上記のスクリプトは、リスト内の各2つの連続した要素(整数、本質的)間の差の平均を把握することになりました。私はこれが本当に何かの近くにないと言っているのでしょうか?それともRubyの知識がないと考えているような根本的なものを見逃していますか?

答えて

7

その男は確かにルビー自身を握っていませんでした。私はなぜ彼がその言語を使うことを選んだのだろうと思う。

ここでは、注釈付きの説明です:あなたは(慣用)Rubyは、いくつかの注釈

values = open("lengths.txt") do |f| 
    # Read it like this: 
    # 
    # Take the list of all lines in a file, 
    # apply a function to each line 
    # The function is stripping the line and turning it 
    # into an integer 
    # (This means the resultant list is a list of integers) 
    # 
    # And then sort it and unique the resultant list 
    # 
    # The eventual resultant list is assigned to `values` 
    # by being the return value of this "block" 
    f.lines.map { |l| l.strip.to_i }.sort.uniq 
end 

# Assign `diffs` to an empty array (instead of using Array.new()) 
diffs = [] 
values.each_index do |i| 
    # Syntactic sugar for `if` 
    # It applies the 1st part if the 2nd part is true 
    diffs << (values[i+1] - values[i]) if i < values.length - 1 
end 

# You can almost read it like this: 
# 
# Take the list `diffs`, put all the elements in a sentence, like this 
# 10 20 30 40 50 
# 
# We want to inject the function `plus` in between every element, 
# so it becomes 
# 10 + 20 + 30 + 40 + 50 
# 
# The colon `:+` is used to refer to the function `plus` as a symbol 
# 
# Take the result of the above summation, divided by length, 
# which gives us average 
delta = diffs.inject(:+)/diffs.length 

# `delta` should now contains the "average of differences" between 
# the original `values` 

# String formatting using the % operator 
# No \n needed since `puts` already add one for us 
puts "delta has the value of %d" % delta 
で、私はあなたが望んで書いた、のように見える「本物」何のより良い理解を得るのを助けるために

# Yes, it reads all lines of a file in words (an array) 
words = File.open("lengths.txt") {|f| f.read }.split 

values = Array.new(0) 
# Yes, to_i convert string into integer 
words.each { |value| values << value.to_i } 
values.sort! 
values.uniq! 

# diffs and s seem unused 
diffs = Array.new(0) 
sum = 0 
s = 0 

# The immediate line below can be read as `for(int index = 0; index < values.length; index++)` 
values.each_index { |index| 
    # index is integer, to_i is unnecessary 
    if index.to_i < values.length-1 then 

     # The `sum` variable is used here 
     # Following can be rewritten as sum += values[i-1] - values[i] 
     sum += values.at(index.to_i + 1) - values.at(index.to_i) 
    end 
} 

puts "delta has the value of\n" 

# Yes, this will eventually print the minimal of the original values divided by 2 
puts values.at(0)/2 

ルビーの真の力をプッシュされることなく、Rubyistsを表現して詰め込むそんなに熱心取得なぜあなたは見ること:P

+0

うわー、それは私がそれを見た場合包括的な答えです!そして、ええ、Rubyはかなり強力に見えます。 –

1
values.each_index { |index| if index.to_i < values.length-1 then sum += values.at(index.to_i + 1) - values.at(index.to_i) end } 

上記の行は、連続する値の差を合計したものです。テストindex.to_i < values.length-1は、values.at(index.to_i + 1)のために、範囲外の配列にアクセスしません。

あなたが正しいです、このコードはあまりできません。ファイルからの最小値の半分だけを出力します。

+0

なぜ整数を再度チェックするのですか?そして、 "index AJJ

+0

はい、 'index'は整数です。ここではto_iは必要ありません。 –

9

説明+リファクタリング(未使用variabl削除された機能的アプローチ、each_cons):

# Read integer numbers from file, sort them ASC and remove duplicates 
values = File.read("lengths.txt").split.map(&:to_i).sort.uniq 

# Take pairwise combinations and get the total sum of partial differences 
partial_diffs = values.each_cons(2).map { |a, b| b - a }.inject(0, :+) 
+0

うわー、私は 'each_cons'を知りませんでした。 – kizzx2

関連する問題