Ruby- split last three fields - ruby

I know split is a useful tool and I know there is a way to do this. I tried a few different methods but couldn't figure it out via google. Can anyone help me.
example1 = "test1,test2,test3,test4,test5"
example2 = "test1,test2,test3,test4,test5,test6,test7"
So I need the result to look like this
example1 = test3,test4,test5
example2 = test5,test6,test7
I would like to keep the comma's too.

example = "test1,test2,test3,test4,test5"
example.split(',')[-3..-1] # => [test3,test4,test5]
Split gives you an array. You can use ranges to select subsets of an array. The negative numbers are counting from the end of the array, so [-3..-1] selects the third last to the last element.

This is basically just split and join on commas. Negative indexes into an array will easily get you the last however-many elements. So I think you want str.split(',')[-3..-1].join(',').

You can also use last(3) instead of [-3..-1], like this:
example = "test1,test2,test3,test4,test5"
example.split(',').last(3).join(',') # => "test3,test4,test5"

Related

How to sort an array in Ruby

Persoane = []
Nume = gets
Persoane.push Nume.split(",")
puts Persoane.sort
I am trying to get an user to input carachters that get split into substrings which get inserted in an array, then the program would output the strings in alphabetical order. It doesnt seem to work and I just get the array's contents, like so:
PS C:\Users\Lenovo\Desktop\Ruby> ruby "c:\Users\Lenovo\Desktop\Ruby\ruby-test.rb"
Scrie numele la persoane
Andrei,Codrin,Bradea
Andrei
Codrin
Bradea
PS C:\Users\Lenovo\Desktop\Ruby>
you can do this :
Nume = gets
puts Nume.split(",").sort
or in 1 line
array = gets.chomp.split(",").sort
The error is because of your use of push. Let's assume that you define the constant Nume by
Nume='Andrei,Codrin,Bradea'
Then, Nume.split(',') would return the Array ['Andrei', 'Codrin', 'Bradea']. When you do a Persoane.push, the whole array is added to your array Persoane as a single element. Therefore, Persoane contains only one Element, as you can verify when you do a
p Persoane
If you sort a one-element array, the result will also be just that one element - there is nothing to sort.
What you can do is using concat instead of push. This would result in Persoane being a 3-element array which can be sorted.
I'm not sure you need use constants here
If you don't need keep user input and use it somewhere, you can just chain methods like this
persons = gets.chomp.split(",").sort
For something a little different, let's not split at all.
people = gets.scan(/[^,]+/).map(&:strip).sort
This will avoid problems like multiple commas in a row yielding empty strings. Of course, you could also avoid that with:
people = gets.split(/\,+/).map(&:strip).sort

aggregate values from specific key in an array of hashes

I'm trying to build an array of values that come from an array of hashes, at the moment my code looks like this:
ids = array_of_hashes.inject([]) do |result,instance|
result << instance[:id]
result
end
I just want to know if there's a more efficient way to do it?
You could change it to look like:
ids = hash.map { |instance| instance[:id] }
Not necessarily more efficient, but easier to read and maintain!
Good luck!
There are two easy ways for it:
1. ids = hash.collect{|h| h[:id]}
2. ids = hash.map{|h| h[:id]}
Now you would ask what is the difference in both? for explanation see this accepted answer

removing duplicates from list of strings (output from Twilio call - Ruby)

I'm trying to display total calls from a twilio object as well as unique calls.
The total calls is simple enough:
# set up a client to talk to the Twilio REST API
#sub_account_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#subaccount = #sub_account_client.account
#calls = #subaccount.calls
#total_calls = #calls.list.count
However, I'm really struggling to figure out how to display unique calls (people sometimes call back form the same number and I only want to count calls from the same number once). I'm thinking this is a pretty simple method or two but I've burnt quite a few hours trying to figure it out (still a ruby noob).
Currently I've been working it in the console as follows:
#sub_account_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#subaccount = #sub_account_client.account
#subaccount.calls.list({})each do |call|
#"from" returns the phone number that called
print call.from
end
This returns the following strings:
+13304833615+13304833615+13304833615+13304833615+13304567890+13304833615+13304833615+13304833615
There are only two unique numbers there so I'd like to be able to return '2' for this.
Calling class on that output shows strings. I've used "insert" to add a space then have done a split(" ") to turn them into arrays but the output is the following:
[+13304833615][+13304833615][+13304833615][+13304833615][+13304567890][+13304833615][+13304833615][+13304833615]
I can't call 'uniq' on that and I've tried to 'flatten' as well.
Please enlighten me! Thanks!
If what you have is a string that you want to manipulate the below works:
%{+13304833615+13304833615+13304833615+13304833615+13304567890+13304833615+13304833615+13304833615}.split("+").uniq.reject { |x| x.empty? }.count
=> 2
However this is more ideal:
#subaccount.calls.list({}).map(&:from).uniq.count
Can you build an array directly instead of converting it into a string first? Try something like this perhaps?
#calllist = []
#subaccount.calls.list({})each do |call|
#"from" returns the phone number that called
#calllist.push call.from
end
you should then be able to call uniq on #calllist to shorten it to the unique members.
Edit: What type of object is #subaccount.calls.list anyway?
uniq should work for creating a unique list of strings. I think you may be getting confused by other non-related things. You don't want .split, that's for turning a single string into an array of word strings (default splits by spaces). Which has turned each single number string, into an array containing only that number. You may also have been confused by performing your each call in the irb console, which will return the full array iterated on, even if your inner loop did the right thing. Try the following:
unique_numbers = #subaccount.calls.list({}).map {|call| call.from }.uniq
puts unique_numbers.inspect

Parse text/json data in Ruby

I am collecting HTTP response and it comes back in the text/json form. The original format is as follows:
{"param" => "value", "interesting_param" => [{"parama1"=>vala1,"parama2"=>vala2,"parama3"=>vala3,"parama4"=>vala4,"parama5"=>vala5},
{"paramb1"=>valb1,"paramb2"=>valb2,"paramb3"=>valb3,"paramb4"=>valb4,"paramb5"=>valb5}]}
When I do a JSON.parse(response.body)["interesting_param"], I can retrieve this output:
{"parama1"=>vala1,"parama2"=>vala2,"parama3"=>vala3,"parama4"=>vala4,"parama5"=>vala5},
{"paramb1"=>valb1,"paramb2"=>valb2,"paramb3"=>valb3,"paramb4"=>valb4,"paramb5"=>valb5}
How can I capture only the following from the full result-set above.
`parama1-vala1`, `parama2-vala2` and `parama5-vala5`
`paramb1-valb1`, `paramb2-valb2` and `paramb5-valb5`
Update
I did try further on this & now I am thinking of making use of loop.
The way I am attempting to do this is:
Find the count of records, for example, if:
test =
{"parama1"=>vala1,"parama2"=>vala2,"parama3"=>vala3,"parama4"=>vala4,"parama5"=>vala5},
{"paramb1"=>valb1,"paramb2"=>valb2,"paramb3"=>valb3,"paramb4"=>valb4,"paramb5"=>valb5}
Then, test.count will be 2.
Now if somehow I can use a loop to iterate over elements in test, then I might be able to capture specific elements.
Thanks.
It looks like you want to map each hash into a list of strings made by joining the string version of the key with the string version of the value, joined by a '-'.
JSON.parse(response.body)["interesting_param"]
The above code should give you a ruby list of hashes.
interesting_bits = JSON.parse(response.body)["interesting_param"]
result = interesting_bits.map{|bit| bit.map{|k,v| "#{k}-#{v}"}}
Something like that should do the trick.
puts result.inspect
#prints
# [ ["parama1-vala1","parama2-vala2","parama3-vala3","parama4-vala4","parama5-vala5"] , ["paramb1-valb1","paramb2-valb2","paramb3-valb3","paramb4-valb4","paramb5-valb5"] ]
I don't understand what criteria you are using for then filtering this down to just 1,2 and 5... but that is easily done too. I would do that to the hashes before converting them to string lists.

English words (ONE, TWO, THREE) to number(1,2,3) in ruby

I am trying to convert words/strings to numbers in Ruby for example:-
ONE => 1
TWO => 2
THREE => 3
FOUR => 4
etc...
I have seen many examples other way around (numbers to words); however, I am not been able to find an example of how to convert words to numbers. It would be great if I can get any insight or help on this.
This might help: http://www.rubyquiz.com/quiz25.html
EDIT: read the question incorrectly. As per my comment below, here's a way you could approach this.
If num_to_word(number) is your method of converting from a number to a word:
def number_hash_creator(min, max)
number_hash = {}
for num in (min..max)
number_hash[num_to_word(num)] == num
end
number_hash
end
Then do something like:
number_hash = number_hash_creator(min, max) # min and max are whatever you need them to be
number_hash['three']
=> 3
You could also append a similar method to the string class so that you could do things like "three".to_number
I created a hash up-to twenty for all words and only for tens(thirty, forty, fifty etc.). Using Reg-ex took off two words and added them for example twenty two is addition of 20+2=22; right now my script only works till hundred, but it can be extended for numbers over 100 and so on.
I think you will find this tutorial very interesting particularly the code near the bottom:
http://pine.fm/LearnToProgram/?Chapter=08

Resources