如何將單詞的結尾與 Ruby 中的哈希進行比較? (How can I compare the ending of a word with a hash in Ruby?)


問題描述

如何將單詞的結尾與 Ruby 中的哈希進行比較? (How can I compare the ending of a word with a hash in Ruby?)

我正在嘗試做一些類似字符串分析器的事情,我需要檢索一個單詞的結尾並將其與哈希的鍵進行比較

word = "Test"
ending_hash = {"e" => 1, "st" => 2}
output = 2

我需要輸出為2大小寫,但實際上我不知道結尾的長度是 1 個字符還是 2 個字符。有可能嗎?


參考解法

方法 1:

Initially, assume that you know that word ends with (at least) one of the keys of ending_hash. You can then write:

word = "Test"
ending_hash = {"e" => 1, "st" => 2}

ending_hash.find { |k,v| word.end_with?(k) }.last
  #=> 2

See Enumerable#find, String#end_with? and Array#last.

The intermediate calculation is as follows:

ending_hash.find { |k,v| word.end_with?(k) }
  #=> ["st", 2]

If you are unsure if any of the keys may match the end of the string, write:

ending_hash = {"e" => 1, "f" => 2} 
arr = ending_hash.find { |k,v| word.end_with?(k) }
  #=> nil
arr.nil? ? nil : arr.last
  #=> nil

or better:

ending_hash.find { |k,v| word.end_with?(k) }&.last
  #=> nil

Here & is the Safe Navigation Operator. In a nutshell, if the expression preceding & returns nil, the SNO immediately returns nil for the entire expression, without executing last.

Even if word must end with one of the keys, you may want to write it this way so that you can check the return value and raise an exception if it is nil.

You could alternatively write:

ending_hash.find { |k,v| word.match? /#{k}\z/ }&.last

The regular expression reads, "match the value of k (#{k}) at the end of the string (the anchor \z)".

Note the following:

{"t"=>1, "st"=>2}.find { |k,v| word.end_with?(k) }&.last
  #=> 1
{"st"=>1, "t"=>2}.find { |k,v| word.end_with?(k) }&.last
  #=> 1

so the order of the keys may matter.

Lastly, as the block variable v is not used in the block calculation, the block variables would often be written |k,_| or |k,_v|, mainly to signal to the reader that only k is used in the block calculation.

方法 2:

If you know there will be only a small number of lengths of endings, it is much faster to check for all possible lengths, than to check for all endings. (It also makes sense to check them from longest to shortest, in case they overlap, otherwise the shorter will never be matched.)

The lazy one‑liner:

(‑2..‑1).lazy.map { |cut| ending_hash[word[cut..]] }.find(&:itself)

The functional version:

(‑2..‑1).inject(nil) { |a, e| a || ending_hash[word[e..]] }

The blunt but moist version:

ending_hash[word[‑2..]] || ending_hash[word[‑1..]]

(by Gregorio PompeiCary SwovelandAmadan)

參考文件

  1. How can I compare the ending of a word with a hash in Ruby? (CC BY‑SA 2.5/3.0/4.0)

#string #hash #ruby






相關問題

VB.net 如何讓流閱讀器忽略某些行? (VB.net how to make stream reader ignore some line?)

Perl Text::CSV_XS 從字符串中讀取 (Perl Text::CSV_XS read from string)

在 D3 中用逗號格式化數字 (Formatting numbers with commas in D3)

我應該使用什麼-String 或 StringBuilder 將 SQL 查詢存儲在使用許多不同 SQL 查詢的代碼中 (what should i use-String or StringBuilder for storing SQL queries in a code which uses many different SQL queries)

在 python 3.5 的輸入列表中添加美元符號、逗號和大括號 (Adding dollar signs, commas and curly brackets to input list in python 3.5)

使用正則表達式處理字符串 (String Manipulation with regular expression)

如何區分數字字符串和字符串? (How do i distinguish between number string and character string?)

如何將單詞的結尾與 Ruby 中的哈希進行比較? (How can I compare the ending of a word with a hash in Ruby?)

在 Python 列表中查找位於特定字符串之間的字符串 (Find Strings Located Between Specific Strings in List Python)

大寫替代字母 (Alternate letters in upper case)

查找 ia strn 列在同一數據框中的列表列中,並創建具有值的第三列 (Find ia a strn column is in a list column in the same data frame and create a 3rd column with a value)

在算術表達式中使用字符串是否安全? (Is it safe to use strings in arithmetic expressions?)







留言討論