Why is my hash autosorting itself? - ruby-on-rails

The actual problem I was originally doing was converting a hash of arrays into an array of hashes. If anyone has any comments on doing the conversion then that's fine but the actual question I have is why the order of the hash keys change after editing them.
I'm fully aware of this question but this is not a duplicate. In fact I'm just having specific toruble in the order they are coming out in.
I have one array and one hash.
The array (#headers) contains a list of keys. #contents is a Hash filled with arrays. As explained, my task is to get an Array of hashes. So here's my code, pretty straightforward.
#headers = (params[:headers])
puts "ORIGINAL PARAMS"
puts YAML::dump(#headers)
#contentsArray = [] #The purpose of this is to contain hashes of each object
#contents.each_with_index do |page,contentIndex|
#currentPage = Hash.new
#headers.each_with_index do |key, headerIndex|
#currentPage[key] ="testing"
end
puts YAML::dump(#currentPage)
#contentsArray[contentIndex] =#currentPage
end
puts "UPDATED CONTENTS"
puts YAML::dump(#contentsArray[0])
Heres the bit I cant wrap my head around. The keys of the original params are in a different order than the updated one.
Note the :puts "ORIGINAL PARAMS" & puts "UPDATED CONTENTS" parts. This is their output:
ORIGINAL PARAMS
---
- " Page Title "
- " WWW "
- " Description "
- " Keywords "
- " Internal Links "
- " External Links "
- " Content files "
- " Notes "
---
UPDATED CONTENTS
---
" WWW ": page
" Internal Links ": testing
" External Links ": testing
" Description ": testing
" Notes ": testing
" Content files ": testing
" Page Title ": testing
" Keywords ": testing
Why is this?
for the record. Printing #currentPage after the header loop gives this:
" WWW ": page
" Internal Links ": page
" External Links ": page
" Description ": page
" Notes ": page
" Content files ": page
" Page Title ": page
" Keywords ": page
So it must be the way the values and keys are assigned to the #currentPage and not when It goes into the array.

In Ruby 1.8+ Hashes are UNSORTED lists
The order in which you traverse a hash by either key or value may seem arbitrary, and will generally not be in the insertion order.
While in RUBY 1.9+ they are sorted in order you push items.
Hashes enumerate their values in the order that the corresponding keys were inserted.
http://apidock.com/ruby/v1_9_2_180/Hash

This is because Ruby's Hash type uses an hash table data structure internally, and hash tables do not keep track of the order of their elements.
Ruby1.9's Hash uses a linked hash table, which keeps track of the ordre of their elements.
So in Ruby1.8 hashes are unsorted, and in Ruby1.9 hashes are sorted.

Related

How to use a variabe value to name a file using SPSS syntax?

I have a data set with 100+ variables for each of many people.
I have two variables for the person's name: lastname and firstname.
How can I create an output file using the names (i.e., the values of the variables lastname and firstname)?
I would like to do a split file by lastname firstname and export the data for each person into a text file that uses the person's name as the file name.
Below is what my spss command file is doing now. How can I get the command file to spit out separate files for each person?
SORT CASES BY lastname firstname .
SPLIT FILE BY lastname firstname .
PRINT / " ".
PRINT /
"===================================================================".
PRINT / "Report of Selected Responses from the".
PRINT / "Survey Form Document".
Print /"Responses for Candidate: " .
Print / firstname.
Print / lastname.
PRINT /
"===================================================================".
DO IF (Q1.5month EQ "" OR sysmis(q1.5day) OR sysmis(q1.5year) ).
Print
/ "1.5. Some or all of date of birth left blank".
END IF.
[More such print statements.]
EXECUTE.
SPLIT FILE OFF.
First create an empry string variable and populate it:
String firstname_lastname (A100).
Compute firstname_lastname=concat(rtrim(firstname),"_",rtrim(lastname)).
EXECUTE.
Then go to Data menu, Split into files, select your new firstname_lastname variable as the split variable, and.under options select "value labels". Pick a folder and you are done. Maybe click paste, to have everything in syntax 😉

How to fix this formula - auto-populate " instead of '

I am trying to build an auto-populating string to search my database without getting an error message. I am stumped as to how to make " auto-populate as opposed to '.
I have pulled parts of strings from different places online to create this one (as this is way more complicated than what I have ever written) and as a result, I am struggling to edit the part I need.
="'" & join("' OR '",indirect("A2:A"&text(rows(A:A)-countblank(A:A),"0")), "'")
Actual: 'Football' OR 'football'
Intended: "Football" OR "football"
try it like this:
=""""&TEXTJOIN(""" OR """, 1, A2:A)&""""

Active Record Query 'where' to ignore spaces

How do I get all the records from db that match given string without spaces?
For example:
db record: "Hello beautiful world!"
given string: name = "Hello beau tifulworld !"
Is it possible to make it as Active Record Query?
You can search by name without spaces. Something like this (for postgres):
Model.where("replace(name, ' ', '') = replace(?, ' ', '')", 'Hello beau tifulworld !')
What comes to my mind is that you can search the records by sorted names from both sides.
I mean, first in a new created array with the names and ids of the records you sort the record names, by something like
record.name.chars.sort.join and you also sort your
matching_word = "Hello beautiful world!"
to get !Habdeefilllloortuuw"
Then you can get the ids of the records that match this helper name.
In next step you can get these records from the database.
Good luck!

How to split an array of strings and convert to an array of hashes

I'm having difficulty figuring out how to split the following array and converting it into a format, so I can build an Active Record array of hashes.
My issue stems from writing an application that relies on Nokogiri to scrape information from the web. The data in each row of a table I'm trying to extract, is jammed into a single <td> element. Every row has only one <td> element.
EDIT:
The first webpage contains a <ul> list of a few hundred items and a link to its details page. I iterate through each item, using the link to access the details page for parsing. The table element I'm parsing below is from the details page. If you look at the output of split_array, I give the complete data of the first row (Level 1), then part of the second row (Level 2) to show that it is identical in structure but not in value. Solving the problem for the first row, solves the problem for all 6 rows.
<td>
Level 1
<br>
Attribute A: 24%
<br>
Attribute B: 14%
<br>
Attribute C: 15.5%
</td>
I managed to get the data in the following format as an array of arrays. I did this by splitting the long string with the following code:
row.xpath('tr').each_with_index do |td, j|
split_array << td.text.squish.split('%')
end
Here is the partial output of split_array:
[["Level: 1 Attribute A: 24", "Attribute B: 14", "Attribute C: 15.5"],["Level: 2 Atribute A: 36", ..etc]..etc]
I need to:
get rid of the Level: 1, Level: 2... from the first element in each array
split the Attribute Name and the float values into their own field
convert those parts into an array of hashes that looks similar to this:
[{:statistic => "Attribute A", :level_1 => 24.0, :level_2 =>36},{:statistic => "Attribute B", :level_1 => 14.0,:level_2 => 24},{:statistic => "Attribute C", :level_1 => 15.5, :level_2 => 34}]
I'm asking for code, pseudo code, or ideas that will send me in the right direction to convert my array of arrays into the array of hashes I outlined above.
1) Rather than gulp in a <td> string with different kinds of information and then parse them, I suggest storing them in meaningful variables to begin with. For example, store the level in 1 variable and the array of attribute statistics in another, getting them using the parsing facilities provided by Nokogiri.
2) Regarding these strings:
"Attribute B: 14"
Here is a script containing and illustrating a method that will parse them:
#!/usr/bin/env ruby
def parse_attr_string(s)
a = s.split
name = a[1].gsub(':', '')
value = a[2].gsub('%', '').to_f
[name, value]
end
s = "Attribute B: 14"
name, value = parse_attr_string(s)
puts "Name: #{name}, Value: #{value}" # Name: B, Value: 14.0
3) Regarding the reorganizing of the data, how about trying to figure it out and express it in pseudocode and then posting what you come up with if you have any problems with it?

PostgreSql + Query Statement having \r in between the attributes !

Suppose we have a textarea in which we put example string. Textbox contain :
Earth is revolving around the Sun.
But at the time of saving, I just pressed a enter key after "the sun". Now the statements in texbox ::
Earth is revolving around
the Sun
Now, in database where enter was pressed the \r is stored. Now i am trying to fetch the data but unable, because my query is of such type ::
SELECT * FROM "volume_factors" WHERE lower(volume_notes) like E'atest\\r\\n 100'
Actual data stored in database field
atest\r
100
Please suggest me to solve the issue.I have tried gsub to replace but no change.
search_text_array[1] = search_text_array[1].gsub('\\r\\n','\r\n')
Thanks in Advance !!!
Try this:
update volume_factors set volume_notes = regexp_replace(volume_notes, '\r\n', ' ');
That's to replace crlf with one space for data that is already in the database. You use postgresql's psql to do this.
To prevent new data containing crlf entering database, you should do it in the application. If you use ruby's gsub, do not use single quote, use double quote to recognize \n like this:
thestring.gsub("\n", " ")
Here we can replace \r\n by % to fetch the data.
Seaching Query will be like this ::
SELECT * FROM "volume_factors" WHERE lower(volume_notes) like E'atest% 100'
gsub function ::
search_text_array[1] = search_text_array[1].gsub('\\r\\n','%')

Resources