简体   繁体   English

使用map / select时如何访问当前数组

[英]How do I access the current array when using map/select

I have the following (working) code I'm trying to convert into a more concise snippet using either #map or #select. 我有以下(有效)代码,试图使用#map或#select转换为更简洁的代码段。

def duplicate_string(string)
  s_list = []

  string.downcase.chars.each do |char| 
    if string.index(char) != string.rindex(char) && s_list.include?(char) == false
      s_list << char if char != ' '
    end
  end

  s_list
end

puts duplicate_string("I am a duplicate string") == ["i", "a", "t"] #true

This is what I've come up with so far, but I don't know how to access the current array that's been stored by #map or #select and using self isn't working 到目前为止,这是我想出的,但是我不知道如何访问由#map或#select存储的当前数组,并且使用self无法正常工作

def duplicate_string_with_map(string)
  string.downcase.chars.select { |char| string.index(char) != string.rindex(char) && self.include?(char) == false && char != ' ' }
end

The following code would solve your purpose: 以下代码可以解决您的目的:

def duplicate_string_with_map(string)
  (string.downcase.chars.select { |char| string.index(char) != string.rindex(char) && char != ' ' }).uniq
end

Here you need not check include condition as you are already ensuring string.index(char) != string.rindex(char) . 在这里,您不必检查include条件,因为您已经在确保string.index(char) != string.rindex(char)

However, for a better ruby approach, I would suggest you to re-open String class and write a method there. 但是,对于更好的红宝石方法,我建议您重新打开String类并在其中编写一个方法。

It would look something like this: 它看起来像这样:

class String

  def duplicate_characters_array
    (downcase.chars.select { |char| index(char) != rindex(char) && char != ' ' }).uniq
  end

end

string = "I am a duplicate string"
string.duplicate_characters_array

You don't need to access the array and you don't need to use Array#map . 您不需要访问数组,也不需要使用Array#map

There are many ways to reach the goal. 有很多方法可以达到目标。 One of them is to split the string in chars then group the chars (get a hash), reject the groups of space character and the groups smaller than two elements and return the keys of the remaining groups: 其中之一是将字符串拆分为char,然后将char分组(获取哈希),拒绝空格字符组和小于两个元素的组,然后返回其余组的键:

"I am a duplicate string"
    .downcase
    .chars
    .group_by{|i| i}
    .reject{|k, v| k == ' ' || v.length < 2}
    .keys
# ["a", "i", "t"]

Here we can make use of a helper method, Array#difference . 在这里,我们可以使用辅助方法Array#difference The method is explained here . 该方法在这里说明。 Note that that link contains a link to an SO answer where I cite examples of its use. 请注意,该链接包含一个SO答案的链接,在此我引用其用法示例。 Though I proposed that the method be added to the Ruby core there appears to be little interest in doing so. 尽管我建议将该方法添加到Ruby核心中,但这样做似乎没有什么兴趣。

class Array
  def difference(other)
    h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
    reject { |e| h[e] > 0 && h[e] -= 1 }
  end
end

Here we can use this helper as follows. 在这里,我们可以按如下方式使用此帮助器。

def duplicate_string(str)
  a = str.gsub(/\s/,'').downcase.reverse.chars
  a.difference(a.uniq).uniq.reverse
end

duplicate_string "I am a duplicate string"
  #=> ["a", "i", "t"]

The steps are as follows. 步骤如下。

  str = "I am a duplicate string"
  b = str.gsub(/\s/,'')
    #=> "Iamaduplicatestring"
  c = b.downcase
    #=> "iamaduplicatestring"
  d = c.reverse
    #=> "gnirtsetacilpudamai"
  a = d.chars
    #=> ["g", "n", "i", "r", "t", "s", "e", "t", "a", "c", "i", "l", "p",
    #    "u", "d", "a", "m", "a", "i"]
  e = a.uniq
    #=> ["g", "n", "i", "r", "t", "s", "e", "a", "c", "l", "p", "u", "d", "m"]
  f = a.difference(e)
    #=> ["t", "i", "a", "a", "i"]
  g = f.uniq
    #=> ["t", "i", "a"]
  g.reverse
    #=> ["a", "i", "t"]

The key step is the calculation of f . 关键步骤是f的计算。 For each element c of e , f contains n-1 instances of c , where n is the number of instances of c in a . 对于每个元素cef包含n-1的情况下c ,其中n是实例数ca The method therefore excludes characters other than spaces that appear in the string exactly once. 因此,该方法排除了字符串中仅出现一次的空格以外的字符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM