0

For example, I have the string "The Dark Knight 10.0" and I need to convert it into a key value hash of the form:

The Dark Knight => 10.0

How can I create a block to convert all strings of this form that I fetch from a .db file into a key value hash of the above form?

thanks for the help!

SteenJobs
  • 45
  • 8
  • I would go that your main problem here is why this data is stored that way in your database. This format makes no sense - do you have any control over how data is stored? – BroiSatse Sep 28 '14 at 21:45
  • full control, I'm using sqlite. I'm fairly new to using a database - I need it in this script to record my entries such as "add, update, etc." – SteenJobs Sep 28 '14 at 22:03
  • If you have full controll over it, you need to have separate columns for title and rating, and store the data there. Storing this way will have a major impact on your application performance. How are you storing it at the moment, via rails controller? Suddenly it became a pretty broad question – BroiSatse Sep 28 '14 at 22:04
  • yes it did indeed - I'd do this in private chat although my account is too new. I have the data being saved by title and rating. – SteenJobs Sep 28 '14 at 22:16
  • So why do you need to split the above, it should already come from DB in much more useful form than this string. Could you post more of your code on how you retrieve data from db? – BroiSatse Sep 28 '14 at 22:26
  • Is there a way to speak privately? I feel bad unloading all of my questions/issues here. – SteenJobs Sep 28 '14 at 22:38
  • Unfortunately you do not have enough reputation to go to the chat. :( If you want you can drop me an email and we can try to figure sth out tomorrow. – BroiSatse Sep 28 '14 at 23:04

3 Answers3

1

You need a regular expression to isolate the name of the movie and the rating (if 10.0 is a rating). I'll need more input in order to provide a more accurate regular expression, but for the one above, this does the job (it also takes care if the movie, is say, Transformers 2 9.0, it will correctly take Transformers 2 => 9.0):

def convert_string_into_key_value_and_add_to_hash(string, hash_to_add_to)
  name = string[/^[\w .]+(?=\s+\d+\.\d+$)/]
  number = string[/\d+\.\d+$/].to_f
  hash_to_add_to[name] = number
end

str = "The Dark Knight 10.0"
hash = {}
convert_string_into_key_value_and_add_to_hash(str, hash)
p hash #=> {"The Dark Knight"=>10.0}

The more 'Rubyist' way is to use rpartition:

def convert_string_into_key_value_and_add_to_hash(string, hash_to_add_to)
  p partition = string.rpartition(' ')
  hash_to_add_to[partition.first] = partition.last.to_f
end

str = "The Dark Knight 2 10.0"
hash = {}

convert_string_into_key_value_and_add_to_hash(str, hash)
p hash #=> {"The Dark Knight 2"=>10.0}
daremkd
  • 8,244
  • 6
  • 40
  • 66
  • Try it for `'15.10 to Yuma 7.0'`. :) – BroiSatse Sep 28 '14 at 21:51
  • So I just came up with: myint = "The Dark Knight 10.0".scan(/\d+/).join(".") but what you have is obviously significantly better (I'm amazed at how quickly you can come up with st like that). I'm trying to create a movie ratings database, and trying to load the hash from a db file so I can add, update, etc. I'm defining the var "Movies" with the data loaded from the db file, but I need "Movies" to be a hash with key values. – SteenJobs Sep 28 '14 at 21:59
  • Also, I can't believe you'd even for the sake of an example award Transformers 2 with a 9.0... – SteenJobs Sep 28 '14 at 22:00
  • The problem is, I now can't define hash_to_add_to = movies, because it's part of the definition of "movies".. – SteenJobs Sep 28 '14 at 22:01
  • Don't worry, you'll get better with practice, StackOverflow is an amazing resource to get better at programming. I didn't quite get you, if you need to get only the key values from a hash, then do some_hash.keys (in this instance, you'll get only the list of movies). – daremkd Sep 28 '14 at 22:02
  • If we suppose that hash = {"Transofrmers The Movie"=>10.0} , then hash.keys #=> ['Transformers the Movie'], you can just assign it to a variable, say movies = hash.keys. – daremkd Sep 28 '14 at 22:04
  • I can see why that was confusing: When I run the script and add movies, it adds them to the hash "movies". However, in order to store my entries, I have "movies" being written to a db file. In order to check if I'm adding a movie already in the hash/db, I have the script fetching the db in the beginning and defining "movies" as the data fetched. – SteenJobs Sep 28 '14 at 22:10
0

Assuming you already have the strings in a collection, iterate over them (1), split by the last space (2), and put the result into a hash using the two parts as key/value.

(1) See the 'each' method

(2) See the 'rpartition' method (example here : https://stackoverflow.com/a/20281590/1583220)

Hope it helps.

Community
  • 1
  • 1
0

If you read a file into an array, each element in the array being a line from the file, you will have something like:

arr = ["The Dark Knight 10.0", "The White Knight 9.4", "The Green Knight 8.1"]

There are many ways to divide each string into two parts, for the key and value in a hash. This is one way:

arr.each_with_object({}) do |str,h|
  key, value = str.split(/\s(?=\d)/)
  h[key] = value
end
  #=> {"The Dark Knight"=>"10.0",
  #    "The White Knight"=>"9.4",
  #    "The Green Knight"=>"8.1"}

Here (?=\d) in the regex is called a "positive lookahead".

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100