Найти целочисленные значения (Fixnum) в массиве ruby - PullRequest
2 голосов
/ 24 апреля 2011

У меня есть массив [1, 2, "3", "4", "1a", "abc", "a"] с

  • чистыми целыми числами (1, 2),
  • строковыми целыми числами ("1", "2"),
  • строки ("a", "b") и
  • номера смешанных строк ("1a", "2s").

Отсюда,Мне нужно забрать только целые числа (включая строковые) 1, 2, "3", "4".

Сначала я попробовал с to_i:

arr = [1, 2, "3", "4", "1a", "abc", "a"]
arr.map {|x| x.to_i}
# => [1, 2, 3, 4, 1, 0, 0]

, но этот преобразует "1a" в 1, чего я не ожидаю.

Затем я попытался Integer(item):

arr.map {|x| Integer(x) }  # and it turned out to be
# => ArgumentError: invalid value for Integer(): "1a"

Теперь у меня нет прямого преобразованияварианты тут.Наконец, я решил сделать это так, чтобы преобразовать значения to_i и to_s.Таким образом, "1" == "1".to_i.to_s является целым числом, но не "1a" == "1a".to_i.to_s и "a" == "a".to_i.to_s

arr  = arr.map do |x|
  if (x == x.to_i.to_s)
    x.to_i
  else
    x
  end
end

и

ids, names= arr.partition { |item| item.kind_of? Fixnum }

Теперь я получил массивы целых чисел и строк.Есть ли простой способ сделать это?

Ответы [ 7 ]

5 голосов
/ 24 апреля 2011

Аналогичное решение, предоставленное @maerics, но немного тоньше:

arr.map {|x| Integer(x) rescue nil }.compact
3 голосов
/ 24 апреля 2011
class Array
  def to_i
    self.map {|x| begin; Integer(x); rescue; nil; end}.compact
  end
end

arr = [1, 2, "3", "4", "1a", "abc", "a"]
arr.to_i # => [1, 2, 3, 4]
2 голосов
/ 24 апреля 2011

Эй, спасибо, разбудил мой рубин.Вот мой путь к этой проблеме:

arr=[1,2,"3","4","1a","abc","a"]
arr.map {|i| i.to_s}.select {|s| s =~ /^[0-9]+$/}.map {|i| i.to_i}
//=> [1, 2, 3, 4]
2 голосов
/ 24 апреля 2011

как то так:

a = [1,2,"3","4","1a","abc","a"]



irb(main):005:0> a.find_all { |e| e.to_s =~ /^\d+$/ }.map(&:to_i)
=> [1, 2, 3, 4]
1 голос
/ 24 апреля 2011

Как насчет этого?

[1,2,"3","4","1a","abc","a"].select{|x| x.to_i.to_s == x.to_s}
# => [1, 2, "3", "4"]
1 голос
/ 24 апреля 2011

Я заметил, что большая часть ответа до сих пор меняет значения «3» и «4» на фактические целые числа.

>> array=[1, 2, "3", "4", "1a", "abc", "a", "a13344a" , 10001, 3321]
=> [1, 2, "3", "4", "1a", "abc", "a", "a13344a", 10001, 3321]
>> array.reject{|x| x.to_s[/[^0-9]/] }
=> [1, 2, "3", "4", 10001, 3321]

@ OP, я не проверил свое решение полностью, но пока оно работает (конечно, оно сделано в соответствии с предоставленным образцом), поэтому, пожалуйста, тщательно протестируйте себя.

0 голосов
/ 24 апреля 2011

выглядит довольно просто

arr.select{ |b| b.to_s =~ /\d+$/ }
# or
arr.select{ |b| b.to_s[/\d+$/] }
#=> [1, 2, "3", "4"]
...