Ruby Basic Data Type Conversion

ruby basic data type conversion

Having a 0 at the start of a number makes the interpreter/compiler interpret the following digits as an octal number sequence (base 8) not a decimal number sequence (base 10). Therefore the number you entered is an octal number and not decimal.

You can test this on a scientific calculator by putting it into octal mode and then switching to decimal.

Empty associative array SOAP type conversion

You can wrap your array in a SoapVar class with APACHE_MAP as encoding parameter. Like This:

array(
"options"=>array(
"plans"=>array(
0=>array(
"name"=>"abc",
"product_options"=> new SoapVar(array(), APACHE_MAP),
),
),
),
);

Taking input of two different data type in Ruby

The simplest answer is to replace to_i with to_f (to_float). This will cope with floats, but will convert all your inputs to float, even if an int would do.

You have some other difficulties with your code:

  • X andY are constants, because they start with capital letters. This will cause difficulties if you ever want to reassign them.
  • It expects 2 inputs – no more or no less. A 3rd input will be ignored. If you only have one input, Y will be nil.

To take different types of input, you'll have to parse it intelligently. Here I'm using regular expressions for the parsing. You could take other approaches, eg test if arg.to_i == arg.to_f (false if it's a float, true if it's an int...or if it's neither float nor int).

def parse_input(args)
args.map do |arg|
case arg
when /^-?[\d]+$/
arg.to_i
when /^-?[\d]+\.?[\d]+$/
arg.to_f
else
arg
end
end
end

input = parse_input(gets.split)
input.each { |i| puts "#{i} (#{i.class})"}

You can take that input array and pass it round other functions, without it having to tontain exactly 2 members.

How to convert hash values into appropriate data types for SQL queries

You can do things to normalize your data like this:

def normalize(value)
case (value)
when 'true'
true
when 'false'
false
when 'null','nil'
nil
when /\A-?\d+\z/
value.to_i
when /\A-?\d+\.\d+\z/
value.to_f
else
value
end
end

There's risks here in interpreting the values incorrectly, like if a field could contain the string literal "true" and you want that preserved this will mangle it, and likewise, phone numbers of the form 8889991111 will be coerced into numbers that might not fit in 32-bit forms, so that could be a problem for some systems.

The reason there's no automatic way is because converting it like this isn't hard, plus a lot of the conversion is highly contextual.

How to implicitly convert custom class to integer in Ruby?

For ax + 3 to work, you need to define + method on your class:

def +(other)
@value + other
end

However, 3 + x will still result in an error as the interpreter won't have clue how to combine a Fixnum with the instance of your class. To fix this, define the coerce method like this:

def coerce(other)
if other.is_a?(Fixnum)
[other, @value]
else
super
end
end

I won't go into detail on how coerce works as we already have a great answer here.

Please explain how Ruby interprets numbers

Numbers starting with 0 are interpreted as octal numbers.

010 => 8
020 => 16
0777 => 511

Converting a ruby structure to a hash

When trying to tackle problem like this in Ruby, it's useful to think of it in terms of transformations on your data. The Ruby Enumerable library is full of methods that help you manipulate regular data structures like Array and Hash.

A Ruby solution to this problem looks like:

def desavon(data)
case (data)
when Hash
if (data[:item])
data[:item].collect do |item|
{ item[:key] => desavon(item[:value]) }
end
else
# raise error?
end
else
data
end
end

Here's some sample input data and sample output:

input = {
item: [
{
key: "result",
value: "success"
},
{
key: "data",
value: {
item: [
{
key: "displayName",
value: "Matt"
},
{
key: "messages",
value: {
item: [
{
key: 'messageName',
value: 'Test Message'
}
]
}
}
]
}
}
]
}

desavon(input)
# => [{"result"=>"success"}, {"data"=>[{"displayName"=>"Matt"}, {"messages"=>[{"messageName"=>"Test Message"}]}]}]

I think this version looks better, output-wise, but that's a call you'll have to make:

def desavon(data)
case (data)
when Hash
if (data[:item])
Hash[
data[:item].collect do |item|
[ item[:key], desavon(item[:value]) ]
end
]
else
# raise error?
end
else
data
end
end

desavon(input)
# => {"result"=>"success", "data"=>{"displayName"=>"Matt", "messages"=>{"messageName"=>"Test Message"}}}

Note that the case statement here is really the key, it allows you to quickly differentiate between different types of data you're converting, and the Hash[] method converts key-value pairs into the Hash structure you're looking for.

This is similar to your attempt, but just passes through content it doesn't recognize as-is.

Convert array of strings to an array of integers

To convert a string to number you have the to_i method.

To convert an array of strings you need to go through the array items and apply to_i on them. You can achieve that with map or map! methods:

> ["", "22", "14", "18"].map(&:to_i)
# Result: [0, 22, 14, 18]

Since don't want the 0 - just as @Sebastian Palma said in the comment, you will need to use an extra operation to remove the empty strings: (The following is his answer! Vote for his comment instead :D)

> ["", "22", "14", "18"].reject(&:empty?).map(&:to_i)
# Result: [22, 14, 18]

the difference between map and map! is that map will return a new array, while map! will change the original array.



Related Topics



Leave a reply



Submit