Match specific substring with string in ruby on rails [closed] - ruby-on-rails

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am working on ruby on rails project and I want to match specific substring with string suppose part1_hello_part2,part3_hii_part4 this is 2 strings and I want to match with the substring _hello_
Items array:
[
{
id:1,
name:part1_hello_part2,
},{
id:2,
name:part3_hii_part4,
}
...
...
{
}
]
for item in #items
if item.name.to_s.match? /\b.*?_hello_.*?\b/
#data.push item
end
end
In the loop of items, I have strings with the name field if match with a specific substring then item push in the data variable. how can I do this?
Update: Actually I want to push the matched data(*_hello_*) in new array #data so I use that in another process

It's not clear what #items is. If it's an ActiveRecord::Relation, then you probably just want to use a query. If it's some other enumerable, like an Array...
item in #items isn't very rubyish, so you might consider:
#items.each do |item|
if item.name.to_s.match? /\b.*?_hello_.*?\b/
#data.push item
end
end
But, #data.push suggests you're building an array, so you might consider:
#data = #items.each_with_object([]) do |item, to_return|
if item.name.to_s.match? /\b.*?_hello_.*?\b/
to_return.push item
end
end
But, each_with_object is a long walk when you have select, so you might consider:
#data = #items.select do |item|
item.name.to_s.match? /\b.*?_hello_.*?\b/
end
Now, you also have include?, so you might consider:
#data = #items.select do |item|
item.name.to_s.include?('_hello_')
end
At that point, you might want to get it all onto one line, so you might consider:
#data = #items.select { |item| item.name.to_s.include?('_hello_')}
You might want to compact that a little more, so you might consider:
#data = #items.select { |item| item.name.to_s['_hello_'] }

As you have probably tried out already by yourself using irb,
'part1_hello_part2'.match? /\b.*?_hello_.*?\b/
returns true, so the problem is not the matching part (although you probably should have written it better as .include?('_hello_'), which looks - at least to me - simpler and easier to understand than your obscure regexp.
If the matching does not work, it means that the left side is not the string what you expect it to be. At the very least, you should output item.name.to_s for debugging purposes. You did not show what #items is. You only said that it is an Array and show a printed representation of its content, which is not the same as showing what the content really is. From the display, it looks like the array elements were hashes, but in this case, I would expect that the elements were accessed by item[:name]. But if ìtemis not just a Hash, but an object which understands the name` method, this is, of course, a correct usage.
Aside from this, and assuming that #data understands the method push, your code looks fine, and you need to ask more precisely, which of the statements you have posted, does not yield the expected outcome.

Related

finding an element in an array without using include? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have an array of objects in which I need to check if it meets a specific criteria.
What I've done is looped through the array and then matched it with the ruby include? object. Problem is I've noticed that there are instances where this causes some codes to return true, when they really should be returning false.
group.plan_codes.each do |code|
normalized_plan_code = code.upcase.gsub(" ", "").gsub("+", "")
normalized_plan_code.include? coverage['plan_description'].upcase.gsub(" ", "").gsub("+", "")
end
I'm basically taking these group.plan_codes and matching them with the coverage['plan_description']. Problem I found was that if the code was something like group plan submitting a code like not group plan would still return true because the group plan is included in the plan description
Would anyone know a better way about doing this? I was thinking it could stop looking after the first element is completed, but am a little caught up on the ruby detect
Use a Regex or a straight equality test (==). For sake of clarity, let's assume (that I'm understanding your question correctly and) that you have an array such as:
plans = [ 'not group plan', 'group plan' ]
and you are trying to find the second element:
including = 'group plan'
plans.detect { |plan| plan.include?(including) }
this returns "not group plan", the first element, because it also includes the string 'group plan'. To remedy that, using regex you could use something like:
plans.detect { |plan| plan.match?(/\A#{Regexp.escape(including)}\z/) }
Now, this returns the second element, because you're looking for an exact match. Since it is an exact match, though, you could also use something simpler:
plans.detect { |plan| plan == including }
What the regex gives you is if each plan can include multiple items:
plans = ['plan a,not group plan,plan b', 'plan a,group plan,plan b']
Which is a comma separated list of plan codes and you're looking for any plan that includes 'group plan', now you can use the regex:
plans.detect { |plan| plan.match?(/,#{Regexp.escape(including)},/) }
and have the second element returned. You'll need to work the regex into a format that works for how you are saving the plan codes (in this example, I chose comma separated list, you might have tabs or semicolons or whatever else. If you have just a white space separated list of codes that can contain whitespace, you need to do more work and reject any items that include any codes that are longer and include the code you're looking for.

update_attributes inside each rails

I have array of data
array = [1,2,4,6]
and what i want it update my model like this
array.each do |a|
Mymodel.all.each do |mm|
mm.update_attributes(name: a)
end
end
but problem is when im trying to do this
update_attributes only with last a
at the end all objects have name 6
How can fix it?
because thats what you are doing, you are running each loop over the array but you are doing the same.
first iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 1)
end
second iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 2)
end
last iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 6)
end
so you just update every time the attribute name to the element in the array. and the last one is there to keep.
your logic is incorrect.
That's logical. For every element in the array you're updating all the model records. So first you're updating all your model entries with the first value in your array, being 1, then you're doing the same for very every model entry only with the value 2. Last value in your array is 6 so you're setting all the values in your model to name with the value 6.
I'm not sure what you're trying to accomplish but from your question I assume you want to update your model in order of your array. So something like this.
model_entries = Mymodel.all
array.each do |value, index|
model_entries[index].update_attributes(name: value)
end
That's one solution, but it seems to me that's something wrong with your base logic here. From where I stand this is certainly something you want to solve in a different way. I can't really go into detail here as I don't know enough about what it is you're trying to achieve

rails each loop with from to

In my controller i fetch 9 row's for object organizations.
#organizations = Organization.where(parent_id: 1).order(city_id: :asc, is_vip: :desc, title: :asc).limit(25).sample(9)
and then in view i must separate this 9 value's to 3 view loops, like first .each do if for row's 1-3, second for 4-6, third 6-9
and i try so:
- #organizations[0..2].each do |org|
...
- #organizations[3..5].each do |org|
...
- #organizations[6..8].each do |org|
...
but it seems that i do something wrong, but what exactly? and how to do it right?
Not sure why your data is duplicated. But you can use the following method for splitting the array into slices
you can use each_slice
#organization.each_slice(3) do |sliced_orgs|
end
Some documentation here
First I don't really get why you use .limit(25).sample(9), you could limit your results to 9 already. But maybe you have some use of the random factor introduced by sample? Strange.
Other than that,
#organizations[0..2].each do |org|
puts org
end
...
should work perfectly fine. If the data is repeated it is because you have multiple times the same entry in your model. sample(9) is taking random unique entries and #organizations[0..2] is a fixed range returning an array or nil. (Rubydoc : ary[range] → new_ary or nil)
In short, nothing wrong with the code but probably somewhere in your data/logic.

Creating a simple array with multiple values in Ruby on Rails

Arrays have always been my downfall in every language I've worked with, but I'm in a situation where I really need to create a dynamic array of multiple items in Rails (note - none of these are related to a model).
Briefly, each element of the array should hold 3 values - a word, it's language, and a translation into English. For example, here's what I'd like to do:
myArray = Array.new
And then I'd like to push some values to the array (note - the actual content is taken from elsewhere - although not a model - and will need to be added via a loop, rather than hard coded as it is here):
myArray[0] = [["bonjour"], ["French"], ["hello"]]
myArray[1] = [["goddag"], ["Danish"], ["good day"]]
myArray[2] = [["Stuhl"], ["German"], ["chair"]]
I would like to create a loop to list each of the items on a single line, something like this:
<ul>
<li>bonjour is French for hello</li>
<li>goddag is Danish for good day</li>
<li>Stuhl is German for chair</li>
</ul>
However, I'm struggling to (a) work out how to push multiple values to a single array element and (b) how I would loop through and display the results.
Unfortunately, I'm not getting very far at all. I can't seem to work out how to push multiple values to a single array element (what normally happens is that the [] brackets get included in the output, which I obviously don't want - so it's possibly a notation error).
Should I be using a hash instead?
At the moment, I have three separate arrays, which is what I've always done, but I don't particularly like - that is, one array to hold the original word, one array to hold the language, and a final array to hold the translation. While it works, I'm sure this is a better approach - if I could work it out!
Thanks!
Ok, let's say you have the words you'd like in a CSV file:
# words.csv
bonjour,French,hello
goddag,Danish,good day
stuhl,German,chair
Now in our program we can do the following:
words = []
File.open('words.csv').each do |line|
# chomp removes the newline at the end of the line
# split(',') will split the line on commas and return an array of the values
# We then push the array of values onto our words array
words.push(line.chomp.split(','))
end
After this code is executed, the words array had three items in it, each item is an array that is based off of our file.
words[0] # => ["bonjour", "French", "hello"]
words[1] # => ["goddag", "Danish", "good day"]
words[2] # => ["stuhl", "German", "chair"]
Now we want to display these items.
puts "<ul>"
words.each do |word|
# word is an array, word[0], word[1] and word[2] are available
puts "<li>#{word[0]} is #{word[1]} for #{word[2]}</li>"
end
puts "</ul>"
This gives the following output:
<ul>
<li>bonjour is French for hello</li>
<li>goddag is Danish for good day</li>
<li>stuhl is German for chair</li>
</ul>
Also, you didn't ask about it, but you can access part of a given array by using the following:
words[0][1] # => "French"
This is telling ruby that you want to look at the first (Ruby arrays are zero based) element of the words array. Ruby finds that element (["bonjour", "French", "hello"]) and sees that it's also an array. You then asked for the second item ([1]) of that array and Ruby returns the string "French".
You mean something like this?
myArray.map{|s|"<li>#{[s[0],'is',s[1],'for',s[2]].join(" ")}</li>"}
Thanks for your help guys! I managed to figure a solution out based on your advice
For the benefit of anyone else who stumbles across this problem, here's my elided code. NB: I use three variables called text, language and translation, but I suppose you could replace these with a single array with three separate elements, as Jason suggests above.
In the Controller (content is being added via a loop):
#loop start
my_array.push(["#{text}", "#{language}", "#{translation}"])
#loop end
In the View:
<ul>
<% my_array.each do |item| %>
<li><%= item[0] # 0 is the original text %> is
<%= item[1] # 1 is the language %> for
<%= item[2] # 2 is the translation %></li>
<% end %>
</ul>
Thanks again!

Most efficent way to get a list of strings with space delimiter

A project can have many tags. When editing a project I'd like to list all tags in a input field (stackoverflow style). In Rails 3 I have the following code, where I push all my names into an array before calling join(' ') but is there a quicker / more elegant way?
#tags = #project.tags
#tags_array = []
#tags.each do |tag|
#tags_array << tag.name
end
#tags_string = #tags_array.join(' ')
Maybe what you want is the Enumerable#collect method:
#tags_string = #project.tags.collect(&:name).join(' ')
Collect comes in handy when you're trying to transform one list into another list of equal size, which is exactly the pattern here.
The &:name part means "call method name on the given object" and is something that could be spelled out as { |t| t.name } equivalently.
The Enumerable library is really great and you should have a look through it and be familiar with the various methods as it can save you a ton of time.
One way is to use threads while iterating through the #tags array. Have a look at this excellent article http://rubysource.com/threading-ruby/
Secondly it seems #tag is an array
I would use map to return an array of names and then join them to a string
names = #tags.map{|tag| tag.name}.join(' ')

Resources