Simple question. I am using Ruby V1.9.3 and I type;
<%= f_array = ['a','b','c'] %><br>
<%= f_array.join(' , ') %><br>
but they show up on the browser as;
["a", "b", "c"]
a,b,c
As far as I remember (until Ruby V1.8.3), it used to show up like;
abc
a,b,c
Did Ruby change their specification or did I miss something??
You error is here
<%= f_array = ['a','b','c'] %>
The statement <%= represents a print statement. Change it to
<% f_array = ['a','b','c'] %>
and the line will not be printed. ["a", "b", "c"] is the result of the inspection of an array.
2.1.5 :003 > puts ['a','b','c'].inspect
["a", "b", "c"]
For what it is worth, the code has another issue. Your view should not contain assignments. That's part of the business logic of your application.
Related
I may not be having the whole picture here but I am getting inconsistent results with a calculation: I am trying to solve the run length encoding problem so that if you get an input string like "AAABBAAACCCAA" the encoding will be: "3A2B3A3C2A" so the functions is:
def encode(input)
res = ""
input.scan(/(.)\1*/i) do |match|
res << input[/(?<bes>#{match}+)/, "bes"].length.to_s << match[0].to_s
end
res
end
The results I am getting are:
irb(main):049:0> input = "AAABBBCCCDDD"
=> "AAABBBCCCDDD"
irb(main):050:0> encode(input)
(a) => "3A3B3C3D"
irb(main):051:0> input = "AAABBBCCCAAA"
=> "AAABBBCCCAAA"
irb(main):052:0> encode(input)
(b) => "3A3B3C3A"
irb(main):053:0> input = "AAABBBCCAAA"
=> "AAABBBCCAAA"
irb(main):054:0> encode(input)
(c) => "3A3B2C3A"
irb(main):055:0> input = "AAABBBCCAAAA"
=> "AAABBBCCAAAA"
irb(main):056:0> encode(input)
(d) => "3A3B2C3A"
irb(main):057:0> input = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'
=> "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB"
irb(main):058:0> encode(input)
(e) => "12W1B12W1B12W1B"
As you can see, results (a) through (c) are correct, but results (d) and (e) are missing some repetitions and the resulting code is several letters short, can you give a hint as to where to check, please? (I am learning to use 'pry' right now)
Regular expressions are great, but they're not the golden hammer for every problem.
str = "AAABBAAACCCAA"
str.chars.chunk_while { |i, j| i == j }.map { |a| "#{a.size}#{a.first}" }.join
Breaking down what it does:
str = "AAABBAAACCCAA"
str.chars # => ["A", "A", "A", "B", "B", "A", "A", "A", "C", "C", "C", "A", "A"]
.chunk_while { |i, j| i == j } # => #<Enumerator: #<Enumerator::Generator:0x007fc1998ac020>:each>
.to_a # => [["A", "A", "A"], ["B", "B"], ["A", "A", "A"], ["C", "C", "C"], ["A", "A"]]
.map { |a| "#{a.size}#{a.first}" } # => ["3A", "2B", "3A", "3C", "2A"]
.join # => "3A2B3A3C2A"
to_a is there for illustration, but isn't necessary:
str = "AAABBAAACCCAA"
str.chars
.chunk_while { |i, j| i == j }
.map { |a| "#{a.size}#{a.first}" }
.join # => "3A2B3A3C2A"
how do you get to know such methods as Array#chunk_while? I am using Ruby 2.3.1 but cannot find it in the API docs, I mean, where is the compendium list of all the methods available? certainly not here ruby-doc.org/core-2.3.1/Array.html
Well, this is off-topic to the question but it's useful information to know:
Remember that Array includes the Enumerable module, which contains chunk_while. Use the search functionality of http://ruby-doc.org to find where things live. Also, get familiar with using ri at the command line, and try running gem server at the command-line to get the help for all the gems you've installed.
If you look at the Array documentation page, on the left you can see that Array has a parent class of Object, so it'll have the methods from Object, and that it also inherits from Enumerable, so it'll also pull in whatever is implemented in Enumerable.
You only get the count of the matched symbol repetitions that occur first. You need to perform a replacement within a gsub and pass the match object to a block where you can perform the necessary manipulations:
def encode(input)
input.gsub(/(.)\1*/) { |m| m.length.to_s << m[0] }
end
See the online Ruby test.
Results:
"AAABBBCCCDDD" => 3A3B3C3D
"AAABBBCCCAAA" => 3A3B3C3A
"AAABBBCCAAA" => 3A3B2C3A
"AAABBBCCAAAA" => 3A3B2C4A
"WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB" => 12W1B12W3B24W1B
Seem to be struggling to get my data in the correct format for use with a highchart's pie chart.
If I force the data as follows my graph appears so I know I've done the integration correctly:
data: [
['Test', 30],
['Other', 70],
]
But when I try and use my actual data, it ain't working.
I've tried the following which doesn't work:
data: <%= Location.browsers.map { |o| [o.type, o.count] }.inspect %>
Have also tried:
data: <%= Location.browsers.map { |o| "#{o.type}, #{o.count}" }.to_json %>
The first one gives me a result like this:
"[[\"Safari\", 6448], [\"Microsoft\", 5253], [\"Microsoft-CryptoAPI\", 5185], [\"Dalvik\", 3870], [\"Chrome\", 3701], [\"Mozilla\", 3239], [\"Android\", 2285], [\"Windows-Update-Agent\", 2018], [\"Internet Explorer\", 1843], [\"Firefox\", 1459]]"
Which looks ok.
What's the correct way to run this query?
data: <%= raw Location.browsers.map { |o| [o.type, o.count] } %>
or
data: <%= raw Location.browsers.map { |o| [o.type, o.count] }.to_s %>
should work.
I
"[[\"A\", 10], [\"B\", 30], [\"C\", 0], [\"D\", -10]]"
II
[["A", 10], ["B", 30], ["C", 0], ["D", -10]]
I & II Are not the same
I is a String while II is a javascript Array<Array<Object>>
In your case the first one is the stringify-ed version of the second. You just need to do the reverse process of this to get back the Array from the String using $.parseJSON() or JSON.parse()
I don't have first hand experience with Ruby, but my guess is something like this will do the job
data: $.parseJSON(<%= Location.browsers.map { |o| [o.type, o.count] }.inspect %>)
Parsing string data into JSON # jsFiddle
I have some code in a view script that iterates through an array of arrays:
<% #rows.each do |data| %>
<%= data[0] %>: <%= data[1] %><br>
<% end %>
How can I easily convert each data array to a hash so that I can refer to each item with a key?
<%= data[:name] %>: <%= data[:email] %><br>
You can refer to the arrays with named values like this:
<% #rows.each do |name,email| %>
<%= name %>: <%= email %><br />
<% end %>
This assumes that every member of the #rows array will be the expected two-value array.
#Zach's answer is ok, but answering strictly what you asked for, it can be done this way:
#rows2 = #rows.map { |row| Hash[[:name, :email].zip(row)] }
#Zach and #tokland have supplied two fine answers. Sometimes it's nice to make first class data objects instead of relying on composition of primitive Hashes and Arrays. Struct is handy for this:
irb> EmailTuple = Struct.new :name, :email
=> EmailTuple
irb> rows = [%w{foo foo#example.com}, %w{bar bar#example.com}]
=> [["foo", "foo#example.com"], ["bar", "bar#example.com"]]
irb> rows2 = rows.map{ |row| EmailTuple[ *row ] }
=> [#<struct EmailTuple name="foo", email="foo#example.com">, #<struct EmailTuple name="bar", email="bar#example.com">]
irb> rows2.map{ |tuple| "#{tuple.name} has email #{tuple.email}" }
=> ["foo has email foo#example.com", "bar has email bar#example.com"]
Is there a one-line way to use include if the array it's searching may not be assigned?
I've tried a lot of variants of
(foo || []).include?(:bar)
but without success
If foo really is nil, as opposed to undefined, then (foo || []).include?(:bar) will do what you want, however if foo is not set to anything yet, then you will get a NameError so we can check for that with a longer oneliner...
defined?(foo) ? (foo || []).include?(:bar) : false
(foo ||= []).include?(:bar)
That will do the trick.
Maybe this?
foo.includes? :bar if foo
Since you are using partials, put this on the top of your partial:
<% foo = [] unless local_assigns.has_key?(:foo) # for Arrays %>
<% foo = {} unless local_assigns.has_key?(:foo) # for Hashes %>
<% foo = "" unless local_assigns.has_key?(:foo) # for Strings %>
etc.
This is the proper way of checking if a variable used in a partial has been set at all.
In the views using the foo partial:
<% render :partial => "foo", :locals {:a => 1, :foo => [2, 3, 4]} %>
<% render :partial => "foo", :locals {:a => 1} %>
In the first case, the foo variable will be [2,3,4] in the foo partial.
In the second case, the foo variable will not be put in local_assigns and will thus be given a default value as per the code above.
i have a string with bunch of break tags.
unfortunately they are irregular.
<Br> <BR> <br/> <BR/> <br /> etc...
i am using nokogiri, but i dont know how to tell it to break up the string at each break tag....
thanks.
If you can break on regular expressions, use the following delimiter:
<\s*[Bb][Rr]\s*\/*>
Explanation:
One left angle bracket, zero or more spaces, B or b, R or r, zero or more spaces, zero or more forward slashes.
To use the regex, look here:
http://www.regular-expressions.info/ruby.html
So to implement iftrue's response:
a = 'a<Br>b<BR>c<br/>d<BR/>e<br />f'
a.split(/<\s*[Bb][Rr]\s*\/*>/)
=> ["a", "b", "c", "d", "e", "f"]
...you're left with an array of the bits of the string between the HTML breaks.
Pesto's 99% of the way there, however Nokogiri supports creating a document fragment that doesn't wrap the text in the declaration:
text = Nokogiri::HTML::DocumentFragment.parse('<Br>this<BR>is<br/>a<BR/>text<br />string').children.select {|n| n.text? and n.content }
puts text
# >> this
# >> is
# >> a
# >> text
# >> string
If you parse the string with Nokogiri, you can then scan through it and ignore anything other than text elements:
require 'nokogiri'
doc = Nokogiri::HTML.parse('a<Br>b<BR>c<br/>d<BR/>e<br />f')
text = []
doc.search('p').first.children.each do |node|
text << node.content if node.text?
end
p text # => ["a", "b", "c", "d", "e", "f"]
Note that you have to search for the first p tag because Nokogiri will wrap the whole thing in <!DOCTYPE blah blah><html><body><p>YOUR TEXT</p></body></html>.