PFKrang February 2016

Ruby read a file, create a hash with a key and data, then sort alphabetically

I have a file like below, which I need to put into a hash:

GHIThree, Line, Number
DEFNumber, Two, Line
ABCLine, Number, One

I need to do is take the first 3 characters and turn that into a key and then the rest of the line into the value.

So when I print the hash it should look something like this:

Keys Values
ABC Line, Number, One
DEF Number, Two, Line
GHI Three, Line, Number

Here is what I've got, its a little all over the place but here it is:

lines = File.open("homework02.txt").read.split
fHash = {}
lines.each do |line|
  next if line == ""
  fHash[line[0..2]] = line[3..-1]
end

f = File.open("homework02.txt")
fHash = {}
loop do
  x = f.gets
  break unless x
  fHash[x[0..2]] = x[3..-1]
end

puts fHash

f.close

Answers


sawa February 2016

fHash  =  fHash.to_a.sort.to_h


Andrey Konoplenko February 2016

Try in this way:

result = {}

CSV.foreach('file.csv', skip_blanks: true) do |row|
  result[row[0].slice!(0..2)] = row
end

result.sort.to_h


Cary Swoveland February 2016

Another way:

fHash = { 4=>1, 1=>1, 3=>2 }

fHash.keys.sort.each_with_object({}) { |k,h| h[k]=fHash[k] }
  #=> {1=>1, 3=>2, 4=>1}

The steps:

a = fHash.keys
  #=> [4, 1, 3] 
b = a.sort
  #=> [1, 3, 4] 
enum = b.each_with_object({})
  #=> #<Enumerator: [1, 3, 4]:each_with_object({})> 

We can view the contents of this enumerator by converting it to an array:

enum.to_a
  #=> [[1, {}], [3, {}], [4, {}]] 

You will see that the value of the hash will change as elements of enum are passed to the block.

The block variables k and h are assigned to the first element of enum:

k,h = enum.next
  #=> [1, {}] 
k #=> 1
h #=> {} 

and the block calculation is performed:

h[k]=fHash[k]
  #=> h[1] = { 4=>1, 1=>1, 3=>2 }[1]
  #   h[1] = 1
h #=> {1=>1} 

The second element of enum is passed to the block and the operations are repeated:

k,h = enum.next
  #=> [3, {1=>1}] 
h[k]=fHash[k]
  #=> h[3] = { 4=>1, 1=>1, 3=>2 }[3]
  #   h[3] = 2
h #=> {1=>1, 3=>2} 

The third and last element of enum is passed to the block:

k,h = enum.next
  #=> [4, {1=>1, 3=>2}] 
h[k]=fHash[k]
  #=> h[4] = { 4=>1, 1=>1, 3=>2 }[4]
  #   h[4] = 1 
h #=> {1=>1, 3=>2, 4=>1} 

Post Status

Asked in February 2016
Viewed 3,874 times
Voted 13
Answered 3 times

Search




Leave an answer