代码之家  ›  专栏  ›  技术社区  ›  not2qubit

如何在Ruby中将一个范围为的值字符串转换为一个数组

  •  2
  • not2qubit  · 技术社区  · 8 年前

    我试图分析一个由 "," ,并将其转换为数字数组。我将此作为输入: "1,3,6-8,5" ,并希望有如下数组: [1,3,5,6,7,8]

    我只能在没有范围的情况下进行,如下所示:

    "12,2,6".split(",").map { |s| s.to_i }.sort #=> [2, 6, 12]
    

    对于范围,我无法做到:

    a = "12,3-5,2,6"
    b = a.gsub(/-/, "..")               #=> "12,3..5,2,6"
    c = b.split(",")                    #=> ["12", "3..5", "2", "6"]
    d = c.sort_by(&:to_i)               #=> ["2", "3..5", "6", "12"]
    e = d.split(",").map { |s| s.to_i } #>> Error
    

    我该怎么做?

    我还想在中使用splat操作符 map ,但splat不接受以下字符串 [*(3..5)]

    4 回复  |  直到 8 年前
        1
  •  4
  •   Aleksei Matiushkin    8 年前
    "12,3-5,2,6".
      gsub(/(\d+)-(\d+)/) { ($1..$2).to_a.join(',') }.
      split(',').
      map(&:to_i)
    #⇒ [12, 3, 4, 5, 2, 6]
    
        2
  •  3
  •   Фил    8 年前
    "1,3,6-8,5".split(',').map do |str|
      if matched = str.match(/(\d+)\-(\d+)/)
        (matched[1].to_i..matched[2].to_i).to_a
      else
        str.to_i
      end
    end.flatten
    

    "1,3,6-8,5".split(',').each_with_object([]) do |str, output|
      if matched = str.match(/(\d+)\-(\d+)/)
        output.concat (matched[1].to_i..matched[2].to_i).to_a
      else
        output << str.to_i
      end
    end
    

    或严格

    RANGE_PATTERN = /\A(\d+)\-(\d+)\z/
    INT_PATTERN   = /\A\d+\z/
    
    "1,3,6-8,5".split(',').each_with_object([]) do |str, output|
      if matched = str.match(RANGE_PATTERN)
        output.concat (matched[1].to_i..matched[2].to_i).to_a
    
      elsif str.match(INT_PATTERN)
        output << str.to_i
    
      else
        raise 'Wrong format given'
      end
    end
    
        3
  •  1
  •   Cary Swoveland    8 年前
    "1,3,6-8,5".split(',').flat_map do |s|
      if s.include?('-')
        f,l = s.split('-').map(&:to_i)
        (f..l).to_a
      else
        s.to_i
      end
    end.sort
      #=> [1, 3, 5, 6, 7, 8]
    
        4
  •  1
  •   sawa    8 年前
    "1,3,6-8,5"
    .scan(/(\d+)\-(\d+)|(\d+)/)
    .flat_map{|low, high, num| num&.to_i || (low.to_i..high.to_i).to_a}
    #=> [1, 3, 6, 7, 8, 5]