Как привести Float к Integer? - PullRequest
1 голос
/ 01 апреля 2020

Я застрял при приведении Float к Integer в функции ниже - она ​​никогда не доходит до v.to_int (извините, я новичок в Ruby, и это код обезьяны). Проблема, которую я пытаюсь решить, - это данные, поступающие из MongoDB, которые должны иметь тип Integer, но иногда во входном потоке присутствуют числа с плавающей запятой (см. Ниже).

Чего я пытаюсь достичь - когда Integer ожидал на определенной позиции - приведение и усечение к Integer, что бы там ни было (обычно Float).

def transform_primitive(v, type=nil)
  case v
  when BSON::ObjectId, Symbol
    v.to_s
  when BSON::Binary
    if type.downcase == 'uuid'
      v.data.to_s.unpack("H*").first
    else
      Sequel::SQL::Blob.new(v.data.to_s)
    end
  when Mongo::DBRef
    v.id.to_s
  when Integer
    v.to_int
  else
    v
  end
end

ввод выглядит следующим образом, поэтому последнее значение 150.0 ожидается равным 150

[ "EUR",  20]
[ "EUR",  30]
[ "EUR",  450]
[ "EUR",  22]
[ "EUR",  150.0]

Используется Ruby 2.7 MongoDB 3.4 Исходная библиотека (Mo SQL) не мое, репо здесь

1 Ответ

5 голосов
/ 02 апреля 2020

Чтобы соответствовать как целым числам, так и числам с плавающей запятой, вам нужно изменить условие when на:

when Integer, Float

или просто when Float, поскольку целочисленный случай уже охватывается else.

Observe:

3.is_a? Integer #=> true
3.is_a? Float #=> false
3.4.is_a? Integer #=> false
3.4.is_a? Float #=> true

В качестве альтернативы вы можете использовать класс Numeri c:

when Numeric

Обратите внимание, что Numeri c включает в себя не только целые числа и числа с плавающей запятой, но также сложные и рациональные числа :

(1+0i).is_a? Numeric

Я думаю, что это должно быть хорошо в вашем случае, но просто указав на это.

Кстати, вместо to_int вы можете использовать round:

3.4.to_i #=> 3
3.6.to_i #=> 3
3.4.round #=> 3
3.6.round #=> 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...