在字符串中查找字母并获取职位 - ruby​​

时间:2016-04-20 02:53:01

标签: arrays ruby

目标是找出字母'a'是否在字符串中,并将三个位置添加到字符串中的'a'出现位置。

因此,如果字符串是'gabe',我的列表看起来就像这个列表= [2,3,4]。 如果字符串是'gabba',则list = [2,3,4,5,6,7]

我当前的代码似乎给了我错误

def nearby_az(string)
list = []
for i in 0..(string.length)
    if string[i] == 'a'
        list.push(i+1)
        list.push(i+2)
        list.push(i+3)
        next
    end
return list

我收到以下错误: (repl):11:语法错误,意外的输入结束,期待keyword_end

你能看出我的逻辑在何处脱落?

2 个答案:

答案 0 :(得分:1)

错误来自于您未使用结束关闭范围块的事实。但还有其他一些观点。我建议你尝试这样的事情:

def nearby_az(str)
  list = Array.new
  pos = -1
  str.each_char do |c|
    pos = pos + 1
    if (c == 'a') then
      list.push(pos+1)
      list.push(pos+2)
      list.push(pos+3)
    end
  end
  list
end

或更好

def nearby_az(str)
  list = Array.new
  nstr = str.each_char.to_a
  nstr.each_index do |i|
    if (nstr[i] == 'a') then
      list.push(i+1)
      list.push(i+2)
      list.push(i+3)
    end
  end
  list
end

(通过使用 nstr 数组的自然索引,您甚至不必创建人工索引)

使用此代码,如果你这样做

puts nearby_az("asdfgaqwer")

根据需要,结果将是[1,2,3,6,7,8]。

请记住,Ruby中不需要返回。默认情况下,方法中计算的最后一个表达式的值将返回给方法调用者。

当然,您可以继续使用自己的方式,这样做:

def nearby_az(string)
  list = []
  for i in 0..(string.length)
    if string[i] == 'a'
      list.push(i+1)
      list.push(i+2)
      list.push(i+3)
    end
  end
  list
end

它会给你相同的结果,虽然我认为第一个代码更容易阅读。

答案 1 :(得分:1)

这是一种更像Ruby的方式。

<强>代码

def indices(str)
  str.each_char.
      with_index.
      select { |c,_| c=='a' }.
      flat_map { |_,i| (i..i+2).to_a }
end

<强>实施例

indices "gabe"
  #=> [1, 2, 3] 
indices "gabba"
  #=> [1, 2, 3, 4, 5, 6] 
indices "abbadabbadoo"
  #=> [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10] 

<强>解释

假设

str = "gagga"

然后步骤如下:

enum0 = str.each_char
  #=> #<Enumerator: "gagga":each_char> 
enum1 = enum0.with_index
  #=> #<Enumerator: #<Enumerator: "gagga":each_char>:with_index> 

仔细检查上述返回值。您可以将enum1视为复合枚举器(尽管Ruby没有这样的概念 - enum1只是一个枚举器)。我们可以通过将enum1转换为数组来查看将select传递给enum1的元素:

enum1.to_a
  #=> [["g", 0], ["a", 1], ["g", 2], ["g", 3], ["a", 4]] 

继续,

a = enum1.select { |c,_| c=='a' }
  #=> [["a", 1], ["a", 4]] 
a.flat_map { |e,i| (i..i+2).to_a }
  #=> [1, 2, 3, 4, 5, 6] 

Enumerable#flat_map的块变量为ei。当a["a", 1])的第一个元素传递给块时,使用并行赋值分配块变量:

e, i = ["a", 1]
  #=> ["a", 1] 
e #=> "a" 
i #=> 1 

并执行块计算:

(i..i+2).to_a
  #=> (1..3).to_a
  #=> [1,2,3]

请注意flat_map相当于:

b = a.map { |e,i| (i..i+2).to_a }
  #=> [[1, 2, 3], [4, 5, 6]] 
c = b.flatten(1)
  #=> [1, 2, 3, 4, 5, 6] 

最后一件事:flat_map的第一个块变量e未在块计算中使用。在这种情况下很常见,_(合法的局部变量)代替该变量。这告诉读者不使用该块变量,也可以减少在块内引入错误的可能性。