Confused about Ruby length property - ruby

Why is the my foo() function printing out the string "YAAR" as having a length of 5?
def foo()
map = Hash.new
File.open('dictionary.txt').each_line{ |s|
word = s.split(',')
if word.any? { |b| b.include?('AA') }
puts word.last
puts word.last.length
end
}
end
someFile.txt
265651,YAAR
265654,YAARS
output
YAAR
5
YAARS
6

You're getting a newline '\n' at the end of both strings. So, your split is receiving:
"265651,YAAR\n"
"265654","YAARS\n"

reading from a file you'll get a new line char (\n) at the end of all the lines (except maybe the last one)
instead of
word = s.split(',')
in your loop, use this
word = s.split(',').map { |s| s.chomp }

Related

Chop last character of string

I want to make program which takes the string and chop last character each time and print result to console:
With an input string of Hello, the result should be:
Hello
Hell
Hel
He
H
This is my code so far:
def test_string
puts "Put your string in: "
string = gets.chomp
while string.length == 0
puts string.chop(/.$/)
end
end
puts test_string
Use chop!:
string = gets.chomp
# Print full string, e.g. "Hello"
puts string
# Print remaining... e.g. "Hell", "Hel", etc.
while string.length != 0
puts string.chop!
end
Following code does not modify the original string
string = gets.chomp
l = string.length
l.times do |i|
puts string[0..(l-i-1)]
end
You can also create an array filling it with the string N times, and for each time, get a character less from it:
str = 'Hello'
Array.new(str.size) { |index| str[0...str.size - index] }.each { |str| p str }
# "Hello"
# "Hell"
# "Hel"
# "He"
# "H

Filter through a text file

I want to sort through a text file and leave only a certain section. I have this text in the text file:
{
"id"=>”0000001”,
"type"=>”cashier”,
"summary"=>”Henock”,
"self"=>"https://google.com/accounts/0000001”,
"html_url"=>"https://google.com/accounts/0000001”
}
{
"id"=>”0000002”,
"type"=>”cashier”,
"summary"=>”Vic”,
"self"=>"https://google.com/accounts/0000002”,
"html_url"=>"https://google.com/accounts/0000002”
}
{
"id"=>”0000003”,
"type"=>”cashier”,
"summary"=>”Mo”,
"self"=>"https://google.com/accounts/0000003”,
"html_url"=>"https://google.com/accounts/0000003”
}
How would I sort it so that only the information with person "Mo" is shown?
This is what I tried:
somefile.readlines("filename.txt").grep /Mo}/i
but it is useless.
Code
def retrieve_block(fname, summary_target)
arr = []
File.foreach(fname) do |line|
next if line.strip.empty?
arr << line
next unless arr.size == 7
return arr.join if arr[3].match?(/\"summary\"=>\"#{summary_target}\"/)
arr = []
end
end
Example
Let's first create a file.
text =<<_
{
"id"=>"0000001",
"type"=>"cashier",
"summary"=>"Henock",
"self"=>"https://google.com/accounts/0000001",
"html_url"=>"https://google.com/accounts/0000001"
}
{
"id"=>"0000003",
"type"=>"cashier",
"summary"=>"Mo",
"self"=>"https://google.com/accounts/0000003",
"html_url"=>"https://google.com/accounts/0000003"
}
_
All of the keys and values represented in this string are surrounded with double-quotes. In the question however, many of these keys and values are surrounded by special characters that have a superficial appearance of a double quote. I have assumed that those characters would be converted to double quotes in a pre-processing step.
FName = "test"
File.write(FName, text)
#=> 325
puts retrieve_block(FName, "Mo")
{
"id"=>"0000003",
"type"=>"cashier",
"summary"=>"Mo",
"self"=>"https://google.com/accounts/0000003",
"html_url"=>"https://google.com/accounts/0000003"
}
This should work because of the consistent format of the file.
To return a hash, rather than a string, a slight modification is required.
def retrieve_block(fname, summary_target)
h = {}
File.foreach(fname) do |line|
line.strip!
next if line.empty? || line == '{'
if line == '}'
if h["summary"] == summary_target
break h
else
h = {}
end
else
k, v = line.delete('",').split("=>")
h[k] = v
end
end
end
retrieve_block(FName, "Mo")
#=> {"id"=>"0000003",
# "type"=>"cashier",
# "summary"=>"Mo",
# "self"=>"https://google.com/accounts/0000003",
# "html_url"=>"https://google.com/accounts/0000003"}

How to use variable of condition inside the block

How can I use the var string of the condition in the return value?
lines = ["dyfögifuödxfghif", "xdghödfx", "abcdefg"]
strings = ["abc", "zzzzzzzzz"]
lines.each do |line|
if strings.any? { |string| line.include?(string) }
return string
end
end
return nil
Datatypes:
lines:Array, line:String, strings:Array, string:String
Desired result:
=> "abc"
I am iterating through a lot of lines and want to check each of them if they include a string inside the array named strings -> until I either find a match, or finished iterating.
This snippet does work, but it does the same thing twice:
lines.each do |line|
if strings.any? { |string| line.include?(string) }
return strings.detect { |string| line.include?(string) }
end
end
return nil
You could use detect:
return strings.detect { |string| lines.any? { |line| line.include?(string) } }
You could use .find with some regex to bring back the first match
strings.find {|word| lines.find {|line| line =~ /#{word}/ } }
=> "abc"
# if you want all matches
strings.select {|word| lines.find {|line| line =~ /#{word}/ } }
=> ["abc"]
If you want the first match:
strings.detect { |string| line.include?(string) }
If you want all matches (in an array):
strings.select { |string| line.include?(string) }
You can do this pretty easily if you compile the list of strings to match into a compact regular expression:
string_rx = Regexp.union(strings)
Then all you have to do is filter out the lines that match and pull off the first one:
lines.grep(string_rx).first
# => "abcdefg"
If you don't want to have to process the entire array and optimize this for performance:
lines.lazy.grep(string_rx).first
# => "abcdefg"
The lazy designator makes each entry flow through the chain to completion rather than each stage buffering up before passing to the next.

Replacing a char in Ruby with another character

I'm trying to replace all spaces in a string with '%20', but it's not producing the result I want.
I'm splitting the string, then going through each character. If the character is " " I want to replace it with '%20', but for some reason it is not being replaced. What am I doing wrong?
def twenty(string)
letters = string.split("")
letters.each do |char|
if char == " "
char = '%20'
end
end
letters.join
end
p twenty("Hello world is so played out")
Use URI.escape(...) for proper URI encoding:
require 'uri'
URI.escape('a b c') # => "a%20b%20c"
Or, if you want to roll your own as a fun learning exercise, here's my solution:
def uri_escape(str, encode=/\W/)
str.gsub(encode) { |c| '%' + c.ord.to_s(16) }
end
uri_escape('a b!c') # => "a%20%20b%21c"
Finally, to answer your specific question, your snippet doesn't behave as expected because the each iterator does not mutate the target; try using map with assignment (or map!) instead:
def twenty(string)
letters = string.split('')
letters.map! { |c| (c == ' ') ? '%20' : c }
letters.join
end
twenty('a b c') # => "a%20b%20c"
If you want to first split the string on spaces, you could do this:
def twenty(string)
string.split(' ').join('%20')
end
p twenty("Hello world is so played out")
#=> "Hello%20world%20is%20so%20played%20out"
Note that this is not the same as
def twenty_with_gsub(string)
string.gsub(' ', '%20')
end
for if
string = 'hi there'
then
twenty(string)
#=> "hi%20there"
twenty_with_gsub(string)
#=> "hi%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20there"

split array element before . eg li.mean-array

I'm new to ruby i would like to know how can i split element containing special character.
I have the following array :
my_array = ["sh.please-word", ".things-to-do" , "#cool-stuff", "span.please-word-not"]
my_array.slice!(0..1)
puts my_array
=>#cool-stuff
=>span.please-word
i want it to split array elements that doesn't start with either a dot(.) or a (#) and return the list like this:
.please-word
.things-to-do
#cool_stuff
.please-word-not
i tried to use the slice method for a string which works perfectly, but when i try with the array element it doesn't work.
this is what i have done so far.
list_of_selectors = []
file = File.open("my.txt")
file.each_line do |line|
list_of_selectors << line.split(' {')[0] if line.start_with? '.' or line.start_with? '#'
end
while line = file.gets
puts line
end
i = 0
while i < list_of_selectors.length
puts "#{list_of_selectors[i]}"
i += 1
end
list = []
list_of_selectors.each { |x|
list.push(x.to_s.split(' '))
}
list_of_selectors = list
puts list_of_selectors
list_of_selectors.map! { |e| e[/[.#].*/]}
puts list_of_selectors
result_array = my_array.map { |x| x[/[.#].*/] }
# => [".please-word", ".things-to-do", "#cool-stuff", ".please-word-not"]
The above uses a regular expression to extract the text, beginning with either a dot(.) or a hashtag (#), and return it in the resulting array.

Resources