Ruby Split Integer Into Array - ruby

I have this value x = 876885 . I want to split that value into the array like [876,885]
This is what I tried
x.to_s[0..2].split(',') #=> ["876"]
How can I get something like [876,885]?

Similar to DigitalRoss's answer.
x.divmod(1000)

[x/1000, x%1000] # => [876, 885]

How's about this:
x = 876885
x.to_s.scan(/.../).map {|e| e.to_i }
=> [876, 885]

If you want to be able to handle numbers of arbitrary length, then you can do it using each_slice:
876885.to_s.each_char.each_slice(3).map{|x| x.join}

How about this?
[x.to_s[0..2], x.to_s[3..-1]]

#DigitalRoss's solution is the best for 6-digit numbers, but here's a more general one:
a = 876885
a.to_s.chars.each_slice(3).map { |a| a.join.to_i }
# ⇒ [
# [0] 876,
# [1] 885
#]

Related

Ruby - hash to array

I have:
a = [{"_id"=>BSON::ObjectId('569a58b8e301d083c300000c')}]
and I want it to be:
[BSON::ObjectId('569a58bee301d083c3000752')]
I was experimenting with
a.map{|e| e.map{|k, v| v }}
but it gives me nested array:
[[BSON::ObjectId('569a58b8e301d083c300000c')]]
I'll appreciate any help.
If you just had a hash:
h = {"_id"=>BSON::ObjectId('569a58b8e301d083c300000c')}
and you wanted to fetch the BSON::ObectId, you would call Hash#[]:
h["_id"] #=> BSON::ObjectId('569a58b8e301d083c300000c')
The same works with map:
a.map { |h| h["_id"] }
#=> [BSON::ObjectId('569a58b8e301d083c300000c')]
A cleaner solution.
a = [{"id"=>"1234"},{"id"=>"9876"}]
a.flat_map(&:values)
=> ["1234", "9876"]
I'd use values, then call flatten.
a.collect(:&values).flatten
Or, if there'll only ever be one value
a[0].values[0]

get the number from string by regex

I have a string like this:
"com.abcd.efghi.pay.0.99"
"com.abcd.efghi.pay.9.99"
"com.abcd.efghi.pay.19.99"
I want get the number(0.99, 9.99, 19.99). I tried to do like this:
"com.abcd.efghi.pay.0.99".scan(/\d/).join
=> "099"
Anyone can help me get the correct result. Thanks in advance!
"com.abcd.efghi.pay.0.99".split(/\D+/, 2).last # => "0.99"
"com.abcd.efghi.pay.9.99".split(/\D+/, 2).last # => "9.99"
"com.abcd.efghi.pay.19.99".split(/\D+/, 2).last # => "19.99"
or
"com.abcd.efghi.pay.0.99".sub(/\D+/, "") # => "0.99"
"com.abcd.efghi.pay.9.99".sub(/\D+/, "") # => "9.99"
"com.abcd.efghi.pay.19.99".sub(/\D+/, "") # => "19.99"
This is pretty simple, regexp for numbers like 0.00 or 00.00:
\d{1,2}.{2,}
\d Any digit
\d{1,2} Between 1 and 2 of digit
. a dot
\d{2,} 2 or more of digit
Example:
>> "com.abcd.efghi.pay.19.99"[/\d{1,2}.{2,}/, 0]
=> "19.99"
>> "com.abcd.efghi.pay.9.99"[/\d{1,2}.{2,}/, 0]
=> "9.99"
You probably want something like this:
\d+(\.\d+)?
which looks for an integer followed by an optional fractional part.
Something like this:
"com.abcd.efghi.pay.0.99".scan(/(\d+[.]\d+)/).flatten.first
# => "0.99"
Without regex:
str = "com.abcd.efghi.pay.0.99"
str.split(".").last(2).join(".") # => "0.99"
You can use this regex in scan:
\b\d+(?:\.\d+)?
You need to use end of the line anchor.
\b\d+(?:\.\d+)?$
Ah, so many ways. Here are a couple more:
str = "com.abcd.efghi.pay.9.99"
str[str.index(/\d/)..-1] #=> "9.99"
str.sub(/.*?(?=\d)/,'') #=> "9.99"

Ruby regex matching overlapping terms

I'm using:
r = /(hell|hello)/
"hello".scan(r) #=> ["hell"]
but I would like to get [ "hell", "hello" ].
http://rubular.com/r/IxdPKYSUAu
You can use a fancier capture:
'hello'.match(/((hell)o)/).captures
=> ["hello", "hell"]
No, regexes don't work like that. But you can do something like this:
terms = %w{hell hello}.map{|t| /#{t}/}
str = "hello"
matches = terms.map{|t| str.scan t}
puts matches.flatten.inspect # => ["hell", "hello"]
Well, you can always take out common subexpression. I.e., the following works:
r = /hello{0,1}/
"hello".scan(r) #=> ["hello"]
"hell".scan(r) #=> ["hell"]
You could do something like this:
r = /(hell|(?<=hell)o)/
"hello".scan(r) #=> ["hell","o"]
It won't give you ["hell", "hello"], but rather ["hell", "o"]

How to get first n elements from Hash in ruby?

I have a Hash and i have sorted it using the values
#friends_comment_count.sort_by{|k,v| -v}
Now i only want to get hash of top five elements .. One way is to use a counter and break when its 5.
What is preferred way to do in ruby ?
Thanks
h = { 'a' => 10, 'b' => 20, 'c' => 30 }
# get the first two
p Hash[*h.sort_by { |k,v| -v }[0..1].flatten]
EDITED:
# get the first two (more concisely)
p Hash[h.sort_by { |k,v| -v }[0..1]]
Can't you just do something like:
h = {"test"=>"1", "test2"=>"2", "test3"=>"3"}
Then if you wanted the first 2:
p h.first(2).to_h
Result:
=> {"test"=>"1", "test2"=>"2"}
New to ruby myself (please be nice if I'm wrong guys!) but does this work?
#friends_comment_count.sort_by{|k,v| -v}.first 5
Works for me in IRB, if I've understood what you're trying to achieve correctly
You can't sort a Hash and that's why sort_by does NOT sort your Hash. It returns a sorted Array of Arrays.
In Ruby 2.2.0 and later, Enumerable#max_by takes an optional integer argument that makes it return an array instead of just one element. This means you can do:
h = { 'a' => 10, 'b' => 20, 'c' => 30 }
n = 2
p h.max_by(n, &:last).to_h # => {"b"=>20, "c"=>30}
Hashes are not ordered by nature (even thought in Ruby implementation they are). Try geting converting your Hash to Array and get [0,4] out of it

Ruby array to string conversion

I have a ruby array like ['12','34','35','231'].
I want to convert it to a string like '12','34','35','231'.
How can I do that?
I'll join the fun with:
['12','34','35','231'].join(', ')
# => 12, 34, 35, 231
EDIT:
"'#{['12','34','35','231'].join("', '")}'"
# => '12','34','35','231'
Some string interpolation to add the first and last single quote :P
> a = ['12','34','35','231']
> a.map { |i| "'" + i.to_s + "'" }.join(",")
=> "'12','34','35','231'"
try this code ['12','34','35','231']*","
will give you result "12,34,35,231"
I hope this is the result you, let me know
array.map{ |i| %Q('#{i}') }.join(',')
string_arr.map(&:inspect).join(',') # or other separator
I find this way readable and rubyish:
add_quotes =- > x{"'#{x}'"}
p ['12','34','35','231'].map(&add_quotes).join(',') => "'12','34','35','231'"
> puts "'"+['12','34','35','231']*"','"+"'"
'12','34','35','231'
> puts ['12','34','35','231'].inspect[1...-1].gsub('"',"'")
'12', '34', '35', '231'
And yet another variation
a = ['12','34','35','231']
a.to_s.gsub(/\"/, '\'').gsub(/[\[\]]/, '')
irb(main)> varA
=> {0=>["12", "34", "35", "231"]}
irb(main)> varA = Hash[*ex.collect{|a,b| [a,b.join(",")]}.flatten]
...
irb(main):027:0> puts ['12','34','35','231'].inspect.to_s[1..-2].gsub('"', "'")
'12', '34', '35', '231'
=> nil
You can use some functional programming approach, transforming data:
['12','34','35','231'].map{|i| "'#{i}'"}.join(",")
suppose your array :
arr=["1","2","3","4"]
Method to convert array to string:
Array_name.join(",")
Example:
arr.join(",")
Result:
"'1','2','3','4'"
array.inspect.inspect.gsub(/\[|\]/, "") could do the trick

Resources