With Ruby how do I split on either one of tow conditions -- wheter there are 3 or more spaces or a tab charadter? I tried this
2.4.0 :003 > line = "a\tb\tc"
=> "a\tb\tc"
2.4.0 :004 > line.split(/([[:space:]][[:space:]][[:space:]]+|\t)/)
=> ["a", "\t", "b", "\t", "c"]
but as you can see, the tab character itself is getting included in my results. The results should be
["a", "b", "c"]
What about just split?
p "a\tb\tc".split
# ["a", "b", "c"]
p "a\tb\tc\t\tc\t\t\t\t\t\t\tc\ts\ts\tt".split
# ["a", "b", "c", "c", "c", "s", "s", "t"]
Although that doesn't split when there are three 3 or more white spaces, this might work:
p "a\tb\tc\t\tc\t\t\ t\t\tc\ts\ts\tt".split(/\s{3,}|\t/)
# => ["a", "b", "c", "c", "t", "c", "s", "s", "t"]
line = "aa bb cc\tdd"
line.split /\p{Space}{3,}|\t+/
#⇒ ["aa bb", "cc", "dd"]
Related
I'm trying to solve Chasing Subs problem. I'm trying to generate that regex according to the input data. The goal is go get all substrings (including overlapped ones) with all unique letters.
I'm trying to use regexp like this:
regexp = /(?=(?<gs>.)(?<gu>[^\k<gs>])(?<gb>[^\k<gs>\k<gu>])(?<gm>[^\k<gs>\k<gu>\k<gb>])(?<ga>[^\k<gs>\k<gu>\k<gb>\k<gm>])(?<gr>[^\k<gs>\k<gu>\k<gb>\k<gm>\k<ga>])(?<gi>[^\k<gs>\k<gu>\k<gb>\k<gm>\k<ga>\k<gr>])(?<gn>[^\k<gs>\k<gu>\k<gb>\k<gm>\k<ga>\k<gr>\k<gi>])(?<ge>[^\k<gs>\k<gu>\k<gb>\k<gm>\k<ga>\k<gr>\k<gi>\k<gn>]))/
"archipelago".scan(regexp) #=> []
"archipelbgo".scan(regexp) #=> []
"brchipelbgo".scan(regexp) #=> []
"zrchipelzgo".scan(regexp) #=> [["z", "r", "c", "h", "i", "p", "e", "l", "z"]]
Why does it behave like this? Why can't it find anything with "b" and "a"? And why does it return only one (incorrect) result with "z"? What am I doing wrong?
I don't think a regular expression is the correct tool for this problem. We could do the following, however.
def substrings(str)
arr = str.chars
(1..str.size).each_with_object([]) { |n,a|
arr.each_cons(n) { |b| a << b.join if b == b.uniq } }
end
substrings("archipelago")
#=> ["a", "r", "c", "h", "i", "p", "e", "l", "a", "g", "o", "ar", "rc", "ch", "hi",
# "ip", "pe", "el", "la", "ag", "go", "arc", "rch", "chi", "hip", "ipe", "pel",
# "ela", "lag", "ago", "arch", "rchi", "chip", "hipe", "ipel", "pela", "elag",
# "lago", "archi", "rchip", "chipe", "hipel", "ipela", "pelag", "elago", "archip",
# "rchipe", "chipel", "hipela", "ipelag", "pelago", "archipe", "rchipel", "chipela",
# "hipelag", "ipelago", "archipel", "rchipela", "chipelag", "hipelago", "rchipelag",
# "chipelago", "rchipelago"]
I have this function in Ruby
def translate word
vowels=["a","e","I","O","U"]
i=1.to_i
sentense=word.split(" ").to_a
puts sentense if sentense.length >=1
sentense.split("")
puts sentense
end
I have this phrase "this is a test phrase " and at first I want to create an array that looks like:
["this","is","a", "test", "phrase"]
Then I want to create another array it to look like:
[["t","h","i","s"],["i","s"],["a"],["t","e","s","t"],["p","h","r","a","s","e"].
I tried
sentense=word.split(" ").to_a
new_array=sentense.split("").to_a
but it didn't work
You could use String#split, Enumerable#map and String#chars:
p "this is a test phrase".split.map(&:chars)
# => [["t", "h", "i", "s"], ["i", "s"], ["a"], ["t", "e", "s", "t"], ["p", "h", "r", "a", "s", "e"]]
string.split(' ') could be written as string.split, so you can omit passing the whitespace in parenthesis.
And this also gives you an array, there's no need to use to_a, you'll have an array like ["this", "is", "a", "test", "phrase"], so you can use map to get a new array and for each element inside an array of its characters by using .split('') or .chars.
def chop_up(str)
str.strip.each_char.with_object([[]]) { |c,a| c == ' ' ? (a << []) : a.last << c }
end
chop_up "fee fi fo fum"
#=> [["f", "e", "e"], ["f", "i"], ["f", "o"], ["f", "u", "m"]]
chop_up " fee fi fo fum "
#=> [["f", "e", "e"], ["f", "i"], ["f", "o"], ["f", "u", "m"]]
chop_up "feefifofum "
#=> [["f", "e", "e", "f", "i", "f", "o", "f", "u", "m"]]
chop_up ""
#=> [[]]
How does Ruby's group_by() method group an array by the identity (or rather self) of its elements?
a = 'abccac'.chars
# => ["a", "b", "c", "c", "a", "c"]
a.group_by(&:???)
# should produce...
# { "a" => ["a", "a"],
# "b" => ["b"],
# "c" => ["c", "c", "c"] }
In a newer Ruby (2.2+?),
a.group_by(&:itself)
In an older one, you still need to do a.group_by { |x| x }
Perhaps, this will help:
a = 'abccac'.chars
a.group_by(&:to_s)
#=> {"a"=>["a", "a"], "b"=>["b"], "c"=>["c", "c", "c"]}
Alternatively, below will also work:
a = 'abccac'.chars
a.group_by(&:dup)
#=> {"a"=>["a", "a"], "b"=>["b"], "c"=>["c", "c", "c"]}
This question already has answers here:
How to dynamically create a local variable?
(4 answers)
Closed 7 years ago.
I'm trying to slice an array into equal sizes (rounded down) and save each section to respective variables.
The method each_slice has worked to grab n-sized blocks. However I can't think of a way to:
iterate over the each's blocks' "sub index"
create a new array for each and give each a unique name.
letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n"]
def groups_of_five(array)
split_array = array.each_slice(5).to_a
#something like the following:
#array(n) = Array[split_array.each {|x| x}]
end
end
The output I'm hoping for:
groups_of_five(letters)
=> array1: ["a,"b","c","d","e"]
=> array2: ["f","g","h","i","j"]
=> array3: ["k","l","m","n"]
Combine each_slice with with_index and you'll have everything you need:
letters.each_slice(5).with_index(1) do |group, index|
puts "array#{index}: #{group.inspect}"
end
Output is:
array1: ["a", "b", "c", "d", "e"]
array2: ["f", "g", "h", "i", "j"]
array3: ["k", "l", "m", "n"]
It's no longer possible to set local variable dynamically in Ruby versions greather than 1.8, so if you want to assign to variables it will have to be instance variables or you could output a Hash.
The following will create instance variables:
def groups_of_five(array)
array.each_slice(5).with_index(1) do |group, index|
instance_variable_set "#array#{index}".to_sym, group
end
end
groups_of_five(letters)
puts #array1 #=> ["a", "b", "c", "d", "e"]
puts #array2 #=> ["f", "g", "h", "i", "j"]
puts #array3 #=> ["k", "l", "m", "n"]
Or this will output a Hash:
def groups_of_five(array)
hash = {}
array.each_slice(5).with_index(1) do |group, index|
hash["array#{index}".to_sym] = group
end
hash
end
hash = groups_of_five(letters)
puts hash[:array1] #=> ["a", "b", "c", "d", "e"]
puts hash[:array2] #=> ["f", "g", "h", "i", "j"]
puts hash[:array3] #=> ["k", "l", "m", "n"]
If you are looking for a hash structure to return from groups_of_five(letters), here's the solution
def groups_of_five(array)
split_array = letters.each_slice(5).to_a
split_array.reduce({}){ |i,a|
index = split_array.index(a) + 1
i["array#{index}"] = a; i
}
end
# groups_of_five(letters)
#=> {"array1"=>["a", "b", "c", "d", "e"], "array2"=>["f", "g", "h", "i", "j"], "array3"=>["k", "l", "m", "n"]}
You could do this:
def group_em(a,n)
arr = a.dup
(1..(arr.size.to_f/n).ceil).each_with_object({}) { |i,h|
h["array#{i}"] = arr.shift(n) }
end
group_em(letters,1)
#=> {"array1"=>["a"], "array2"=>["b"],...,"array14"=>["n"]}
group_em(letters,2)
#=> {"array1"=>["a", "b"], "array2"=>["c", "d"],...,"array7"=>["m", "n"]}
group_em(letters,5)
#=> {"array1"=>["a", "b", "c", "d", "e"],
# "array2"=>["f", "g", "h", "i", "j"],
# "array3"=>["k", "l", "m", "n"]}
A variant is:
def group_em(arr,n)
(1..(arr.size.to_f/n).ceil).zip(arr.each_slice(n).to_a)
.each_with_object({}) { |(i,a),h| h["array#{i}"]=>a) }
end
I have the following arrays:
passing_grades = ["A", "B", "C", "D"]
student2434 = ["F", "A", "C", "C", "B"]
and I need to verify that all elements in the student array are included in the passing_grades array. In the scenario above, student2434 would return false. But this student:
student777 = ["C", "A", "C", "C", "B"]
would return true. I tried something like:
if student777.include? passing_grades then return true else return false end
without success. Any help is appreciated.
PASSING_GRADES = ["A", "B", "C", "D"]
def passed?(grades)
(grades - PASSING_GRADES).empty?
end
similar to what CDub had but without bug. more readable in my opinion
You could have a method that does the difference of the arrays, and if any results are present, they didn't pass:
PASSING_GRADES = ["A", "B", "C", "D"]
def passed?(grades)
grades.all? {|grade| PASSING_GRADES.include?(grade)}
end
Example:
1.9.3-p484 :117 > student777 = ["C", "A", "C", "C", "B"]
=> ["C", "A", "C", "C", "B"]
1.9.3-p484 :118 > passed?(student777)
=> true
1.9.3-p484 :118 > passed?(student2434)
=> false