2014-01-09 124 views
0

ordered_vowel_words方法和ordered_vowel_word?輔助方法接受一個單詞並返回單詞,如果單詞的元音符合(a,e,i,o,u)的順序。這個功能是如何工作的?

我無法理解邏輯。特別是幫助方法中的最後一個塊(0...(vowels_arr.length - 1)).all? do...如何工作。

有人可以解釋這是如何工作的?我不明白如何在range上調用all?

def ordered_vowel_words(str) 
    words = str.split(" ") 

    ordered_vowel_words = words.select do |word| 
    ordered_vowel_word?(word) 
    end 

    ordered_vowel_words.join(" ") 
end 

def ordered_vowel_word?(word) 
    vowels = ["a", "e", "i", "o", "u"] 

    letters_arr = word.split("") 
    vowels_arr = letters_arr.select { |l| vowels.include?(l) } 

    (0...(vowels_arr.length - 1)).all? do |i| 
    vowels_arr[i] <= vowels_arr[i + 1] 
    end 
end 
+0

http://ruby-doc.org/core-2.1.0/Enumerable.html – Beartech

回答

1

我添加了一些意見:)

def ordered_vowel_words(str) 
    # words is a string with words separated by a whitespace. 
    # split generates an array of words from a string 
    words = str.split(" ") 

    # select only the ordered vowel words from the previous array 
    ordered_vowel_words = words.select do |word| 
    ordered_vowel_word?(word) 
    end 

    # join the ordered vowel words in a single string 
    ordered_vowel_words.join(" ") 
end 

def ordered_vowel_word?(word) 
    # THESE ARE THE VOWELS YOU FOOL 
    vowels = ["a", "e", "i", "o", "u"] 

    # transform the word in an array of characters 
    letters_arr = word.split("") 

    # select only the vowels in this array 
    vowels_arr = letters_arr.select { |l| vowels.include?(l) } 

    # generate a range from 0 to the length of the vowels array minus 2: 
    # there is this weird range because we want to iterate from the first vowel 
    # to the second to last; all? when called on a range returns true if... 
    (0...(vowels_arr.length - 1)).all? do |i| 
    # for each number in the range, the current vowel is smaller that the next vowel 
    vowels_arr[i] <= vowels_arr[i + 1] 
    end 
end 

希望這有助於!

編輯我可能會補充說,最後一塊並不覺得Ruby-ish。我建議這個替代實現:

def ordered_vowel_word?(word) 
    vowels = ["a", "e", "i", "o", "u"] 

    # transform the word in an array of characters 
    letters_arr = word.split("") 

    # select only the vowels in this array 
    vowels_arr = letters_arr.select { |l| vowels.include?(l) } 

    # from this array generate each possible consecutive couple of characters 
    vowels_arr.each_cons(2).all? do |first, second| 
    first <= second 
    end 
end 

require 'rspec/autorun' 

describe "#ordered_vowel_word?" do 
    it "tells if word is ordered" do 
    expect(ordered_vowel_word?("aero")).to be_true 
    end 

    it "or not" do 
    expect(ordered_vowel_word?("rolling")).to be_false 
    end 
end 
+0

謝謝「FOOL!」 :) - 你的評論幫助我意識到了一些事情。我跳入'irb',並嘗試了''一個「<」e「',我回到了'真實'。我忘了那個。現在我明白'(0 ...(vowels_arr.length - 1))。all?做|我| vowels_arr [i] <= vowels_arr [i + 1]'正在做。我無法確定它是如何確定訂單是否正確的。那麼現在我意識到了 fyz

+0

我已經添加了更多的Ruby-ish實現,並通過了測試:) Ciao bello! –

+0

另一種方法是令人愉快的。非常好!謝謝,再見! – fyz

0

all?塊基本上遍歷vowels_arr陣列,比較每個值與它的下一個。如果所有的比較返回true那麼all?也將返回true,這意味着數組是有序的。如果其中一個迭代返回false,返回值all?也將是false,這意味着該集合是無序的。

您可以在Rangehttp呼籲all?://www.ruby-doc.org/core-1.9.3/Range.html對象,因爲Range混合在Enumerablehttp://www.ruby-doc.org/core -1.9.3/Enumerable.html模塊,它定義了all?

您可以嘗試在IRB以下驗證這一點:

Range.included_modules # => => [Enumerable, Kernel] 
0
  1. 第一部分(0...(vowels_arr.length - 1))創造多少元音在詞的範圍 0。
  2. all?在該範圍內迭代並返回true如果全部爲 範圍元素的某些條件爲真否則爲false。
  3. do |i|引入了i作爲表示 步驟1中創建
  4. 最後的範圍內的每個元素,條件是在範圍內的每個索引變量的塊,現在由i表示的,它會檢查是否vowels_arr[i] <= vowels_arr[i+1]爲真。