I'm trying to figure out how to check if an element belongs to an array using ruby. I'm reading from a file (say demo.txt) which has comma separated pairs in each line. I'm concatenating these two pairs and pushing it into an array. Later I need to check if a specific value belongs to the array. I can see the array is populated successfully but the second check is unsuccessful, i.e. it can't find the element in the array. 'My demo.txt' is as follows
a, b
c, d
The ruby code goes as follows
array = Array.new
File.readlines('demo.txt').each do |line|
line.slice! ", "
array.push line
end
array.each do|d|
puts d
end
if array.include? 'ab'
puts "correct" #this is not printed
end
How do I check if the array contains the element 'ab'?
There is ab\n in your array.
Instead of
array.each do|d|
puts d
end
use inspect to check the values,
p array
#=> ["ab\n", "cd"]
To fix the issue, use chomp on line
File.readlines('b.txt').each do |line|
line = line.chomp
...
end
Replacing this
if array.include? 'ab'
puts "correct"
end
with this one
if array.find 'ab'
puts "correct"
end
resolves the issue.
Related
I have below code
#ar1 = ('kaje','beje','ceje','danjo');
$m = 'kajes';
my($next) = grep $_ eq 'kaje',#ar1;
print("Position is $next\n");
print("Next is $ar1[$next+1]\n");
print("Array of c is $ar1[$m+3]\n");
print("Array at m is $ar1[$m]\n");
Output seen:
Position is kaje
Next is beje
Array of c is danjo
Array at m is kaje
I want to understand how this works. Here $next is the matched string and i am able to index on that string for given array. Also $m is not found in the array, yet we get output as first element of array.
ALWAYS use use strict; use warnings;. It answers your question.
In one place, you treat the string kaje as a number.
In two places, you treat the string kajes as a number.
Since these two strings aren't numbers, Perl will use zero and issue a warning.
In other words, Next is beje only "works" because kaje happens to be at index 0. I have no idea how why you believe the last two lines work seeing as kajes is nowhere in the array.
You want
# Find the index of the element with value `kaje`.
my ($i) = grep $ar1[$_] eq 'kaje', 0..$#ar1;
I would like to create an array in Ruby rake called ARRAY where each line of an infile ("infile.txt") is an element of the array.
This is how I have tried it so far:
desc "Create new array"
task :new_array do
ARRAY=Array.new
end
desc "Add elements to array"
task :add_elements => [:new_array] do
File.open("infile.txt").each do |line|
ARRAY.push(#{line})
end
end
However, I get the following error:
syntax error, unexpected keyword_end, expecting ')'
for the end after "ARRAY.push(#{line})"
Can someone explain to me what the problem is or let me know of another way to do this?
Many thanks!
Your problem is that you're trying to use string interpolation (#{...}) outside a string:
ARRAY.push(#{line})
# ---------^^^^^^^
You could use string interpolation by throwing in some double quotes:
ARRAY.push("#{line}")
but there's no need to convert a string (line) to an identical string ("#{line}") so you could just push straight onto the array:
ARRAY.push(line)
Or you could just skip all that explicit iteration and use #to_a:
array = File.open("infile.txt").to_a
And if you wanted to strip off the newlines:
array = File.open('infile.txt').map(&:chomp)
As engineersmnky points out in the comments, using File.readlines would be a better approach:
array = File.readlines('infile.txt')
array = File.readlines('infile.txt').map(&:chomp)
#...
And don't forget to check IO as well as File for methods when working with files.
You can also do this:
array = []
IO.foreach("path/to/file.txt") { |line|
array.push(line.chomp)
}
Then if you want to clear the array from empty lines just use delete:
array.delete("")
My end goal is to compare values from a file to the records I’m pulling back from a database.
I have a text file with the following structure:
123,55,66
555,99,109
324,100,800
467,200,300
I then pull back records from a database and loop through them one by one.
sth.fetch do |row|
validate = "#{row[0]},#{row[20]},#{row[21]}"
names = File.readlines('results.txt')
matches = names.select { |name| name[/#{validate}/i] }
p "Result matches as expected: #{matches}"
end
so validate builds me the same format string as per the examples above... I then read all lines of the file and move them into an array and then compare. So this is great it gives me all matches but doesn't tell me rows that don't exist on the file?
So alternatively I tried
sth.fetch do |row|
File.open('results') do |f|
f.each_line do |line|
if line == validate
puts "detail: #{line}"
else
puts "detail: #{validate}"
end
end
end
end
But this then reads each line for every row and compares so it half achieves what I am after.
So I want to take my 'validate' string and read the contents of the file to see if a row matches and then print out it's a match. Alternatively if I pull back a record and it doesn't match the file then I just want one does not match message.
Thanks
I would try the following
names = File.readlines('results.txt').map(&:chomp)
sth.fetch do |row|
validate = "#{row[0]},#{row[20]},#{row[21]}"
# for direct compare
# if names.include?(validate)
# Or for Regexp
if names.grep(/#{validate}/i).any?
p "Result matches as expected: #{matches}"
else
p "Result does not matches as expected: #{matches}"
end
end
all_matches.uniq!
I am trying to create a ruby class for a game called times up. Essentially, i want the following functionality to start with:
each instance of the class is a game.
Each game has an array of words which are input by the players.
the class should enable getting a random element out of the array of words and subsequently removing that elemennt from play.
When all the words are out of the "hat", the game should be able to refresh the array to its original content, simulating putting the words back into the hat for the next round.
It is this last point that I am having trouble with.. I tried to create a dummy array or a base array that is not modified and then just set the emptied array to the base array at the end of a round but this only results in me removing elements from the base array in the second round and being left with two empty arrays at the end of the second round :( how do i create a copy which will not be modified??
Here is my code:
class TimesUp
def initialize
#hat = []
#basehat = []
end
def NewWord(word)
#hat.push(word)
#basehat.push(word)
end
def grab
if #hat.empty?
puts "End of round!"
else
l = #hat.length
word = rand(l)
puts #hat[word]
#hat.delete_at(word)
end
end
def printout
puts #hat
end
# here is where i try to set the game array to the 'base' array.
def refresh
#hat = #basehat
#basehat = #basehat
end
end
Use Object#dup, and clone might also be an option.
def refresh
#hat = #basehat.dup
#basehat = #basehat.dup
end
In ruby and other languages, I can create an array, push an arbitrary number of strings and then join the array:
ary=[]
...
ary.push some_str
ary.push some_other_str
...
result = ary.join ""
How do I accomplish this in matlab?
User story: my plot legend is composed of a variable number of strings. The number of strings is determined runtime, so I want to declare the array, add strings dynamically and then join the array to the legend string in the end of the script.
In MATLAB, String joining happens like the following
a = 'ding';
b = 'dong';
c = [a ' ' b]; % Produces 'ding dong'
P.S. a typeof(c,'char') shows TRUE in MATLAB because it "joins" all characters into C.
Suppose you want to start with an empty char placeholder. You can do this.
a = ``; % Produces an empty character with 0x0 size.
Then you can keep adding to the end of it; like this:
a = [a 'newly added'] % produces a = "newly added"
To prove that it works, do this again:
a = [a ' appended more to the end.'] % produces a = "newly added appended more to the end."
You can always use the end keyword that points to the last index of an array, but in this case you need to append to end+X where X is the extra number of characters you are appending (annoyingly). I suggest you just use the [] operator to join/append.
There is also this strjoin(C, delim) function which joins a cell C of strings using a delim delimiter (could be whitespace or whatever). But cheap and dirty one is the one I showed above.