Ruby(v 2.3.1)。。split数组上的每个方法都没有任何逻辑顺序

时间:2017-01-25 00:53:31

标签: arrays ruby string each

我有一个简单的字符串:

  

"西北东南"

我想拆分到子字符串中并将它们作为子数组放入一个数组中,即:

[["direction", "north"], ["direction", "south"], ["direction", "east"], ["direction", "west"]]

但是,.each方法似乎既不按字母顺序也不按顺序输入元素。

.each方法似乎按此顺序通过拆分字符串:

  1. "北" (第一个子串)[按字母顺序排列]
  2. "南" (thirdsub-string)[按字母顺序排列]
  3. "西" (第二个子串)[按字母顺序排列]
  4. "东" (最后一个子串)[按字母顺序排列]
  5. 它绝对不能按字母顺序通过子字符串,也不能以相反的顺序通过它们,而是从第一个子字符串开始,以最后一个字符串结尾,开关中间的琴弦。

    我无法解决这个问题。

    这是我的代码:

    class Lexicon
    
      def scan(stuff)
    
        words = stuff.split
    
        #Empty arrays to easily push split words into
        @direction_array = []
    
        #Lexicons of different kinds of words
        @directions = ["north", "south", "east", "west", "down", "up", "left", "right", "back"]
    
        puts "This the original set"
        print words, "\n"
    
        while words.any? == true
          words.each do |word|
            if @directions.include? word
              puts "This is the word I selected: #{word}"
              @direction_array.push(['direction', word])
              words.delete word
              print @direction_array
              puts "This is what remains in the words set: #{words}"
            else
              "This word does not belong."
              words.delete word
              # puts "This is what remains in the words set: #{words}"
            end
          end
        end
    
        if @direction_array.any? == true
          puts "This is what we have in the direction array:"
          print @direction_array, "\n"
          return @direction_array
        else
          puts "Nothing to show for our efforts"
        end
      end
    end
    
    testing = Lexicon.new()
    testing.scan("north south east west")
    

4 个答案:

答案 0 :(得分:3)

如果从数组中删除元素,则删除元素留下的孔右侧的所有元素都会向左移动以填补空白。

您正在迭代阵列时删除阵列中的元素。如果您只删除尚未迭代的元素,那就没关系。但是如果你删除了一个已经迭代过的元素,那么删除元素右边的所有元素(包括迭代的元素)都会向左移动以填补空洞由删除的元素左侧,这会导致您跳过下一个元素。

在迭代数据结构时,永远不会改变数据结构,除非将显式记录为安全的事情。

答案 1 :(得分:2)

以下是关于如何使其在Ruby方面更传统的一些想法:

class Lexicon
  # Declare things that are repeatedly used without being modified as
  # constants at the class-level.
  DIRECTIONS = %w[ north south east west down up left right back ]

  def scan(stuff)
    # Split the string and select all the words that are present
    # in the DIRECTIONS above.
    stuff.split.select do |word|
      DIRECTIONS.include?(word)
    end.map do |word|
      # Transform these into [ 'direction', x ] pairs
      [ 'direction', word ]
    end
  end
end

如果您将代码整理成简洁明了的块,将您的意图表达为一系列简单的转换,那么代码就很容易理解。请注意,此处不需要显式return,因为默认情况下会隐式返回该操作。

为了锻炼它,你得到了这个:

testing = Lexicon.new
testing.scan("north south east west")
# => [["direction", "north"], ["direction", "south"], ["direction", "east"], ["direction", "west"]]

p方法在显示变量内容时非常方便,用于测试任意代码的irb工具也是如此。

我认为原始代码中的一些问题来自使用迭代和删除方法而不是使用reject过滤器方法或select。从你正在迭代迭代的数组中删除东西通常会产生反效果,并且从数组中删除内容实际上计算成本非常高,因此构建仅包含所需元素的新数组更容易。 / p>

答案 2 :(得分:2)

Len(val) < 9

答案 3 :(得分:0)

你可以采取这种方法:

"north west south east".split.collect { |direction| ['direction', direction] }

将您的路线分成数组的元素,然后按照您的要求收集它们。