How to list my results in a for loop - grails

If i have this snippet from my action
for (c in AuthorList){
def bookCount = Book.countByName(c)
}
How do i make my bookCount into a list

for loop is not required at all. ;)
authorList.collect { Book.countByName( it ) }
should give the list you are looking for.

Try to use <<
def list = []
for (c in AuthorList){
def bookCount = Book.countByName(c)
list << bookCount
}

Related

Ruby split string

String = "Mod1:10022932,10828075,5946410,13321905,5491120,5030731|Mod2:22704455,22991440,22991464,21984312,21777721,21777723,21889761,21939852,23091478,22339903,23091485,22099714,21998260,22364832,21939858,21944274,21944226,22800221,22704443,21777728,21777719,21678184,21998265,21834900,21984331,22704454,21998261,21944214,21862610,21836482|Mod3:10828075,13321905,5491120,5946410,5030731,15806212,4100566,4787137,2625339,2408317,2646868,19612047,2646862,11983534,8591489,19612048,10249319,14220471,15806209,13330887,15075124,17656842,3056657,5086273|Mod4:10828075,5946410,13321905,5030731,5491120,4787137,4100566,15806212,2625339,3542205,2408317,2646862,2646868|Mod5:10022932;0.2512,10828075;0.2093,5030731;0.1465,5946410;0.1465,4787137;0.1465,2625339;0.0143,5491120;0.0143,13321905;0.0143,3542205;0.0143,15806212;0.0119,4100566;0.0119,19612047;0.0100,2408317;0.0100"
How can I split it out so that I can get each title(Mod1, Mod2..) and the ID's that belong to each title.
This is that I've tried so far, which is removing everything after the pipe, which I dont want.
mod_name = string.split(":")[0]
mod_ids = string.split(":")[1] #This gets me the ID's but also include the |Mod*
ids = mod_mod_ids.split("|").first.strip #Only returns Id's before the first "|"
Desired Output:
I need to save mod_name and mod_ids to their respective columns,
mod_name = #name ("Mod1...Mod2 etc) #string
mod_ids = #ids (All Ids after the ":" in Mod*:) #array
I think this does what you want:
ids = string.split("|").map {|part| [part.split(":")[0], part.split(":")[1].split(/,|;/)]}
There are a couple of ways to do this:
# This will split the string on "|" and ":" and will return:
# %w( Mod1 id1 Mod2 id2 Mod3 id3 ... )
ids = string.split(/[|:]/)
# This will first split on "|", and for each string, split it again on ":" and returs:
# [ %w(Mod1 id1), %w(Mod2 id2), %w(Mod3 id3), ... ]
ids = string.split("|").map { |str| str.split(":") }
If you want a Hash as a result for easy access via the titles, then you could do this:
str.split('|').inject({}){|h,x| k,v = x.split(':'); h[k] = v.split(','); h}
=> {
"Mod1"=>["10022932", "10828075", "5946410", "13321905", "5491120", "5030731"],
"Mod2"=>["22704455", "22991440", "22991464", "21984312", "21777721", "21777723", "21889761", "21939852", "23091478", "22339903", "23091485", "22099714", "21998260", "22364832", "21939858", "21944274", "21944226", "22800221", "22704443", "21777728", "21777719", "21678184", "21998265", "21834900", "21984331", "22704454", "21998261", "21944214", "21862610", "21836482"],
"Mod3"=>["10828075", "13321905", "5491120", "5946410", "5030731", "15806212", "4100566", "4787137", "2625339", "2408317", "2646868", "19612047", "2646862", "11983534", "8591489", "19612048", "10249319", "14220471", "15806209", "13330887", "15075124", "17656842", "3056657", "5086273"],
"Mod4"=>["10828075", "5946410", "13321905", "5030731", "5491120", "4787137", "4100566", "15806212", "2625339", "3542205", "2408317", "2646862", "2646868"],
"Mod5"=>["10022932;0.2512", "10828075;0.2093", "5030731;0.1465", "5946410;0.1465", "4787137;0.1465", "2625339;0.0143", "5491120;0.0143", "13321905;0.0143", "3542205;0.0143", "15806212;0.0119", "4100566;0.0119", "19612047;0.0100", "2408317;0.0100"]
}
Untested:
all_mods = {}
string.split("|").each do |fragment|
mod_fragments = fragment.split(":")
all_mods[mod_fragments[0]] = mod_fragments[1].split(",")
end
What I ended up using thanks to #tillerjs help.
data = sting.split("|")
data.each do |mod|
module_name = mod.split(":")[0]
recommendations = mod.split(":")[1]
end

Grails query not inList

I'm writing a criteria to make a query, but I can't figure out how to negate an inList criteria...Is there a way to do something like:
def result = c {
not inList('id', ids)
}
Thanks
Your criteria should like this...
def ids = [1, 2, 3];
def c = Foo.createCriteria();
def results = c.list {
not {'in'("id",ids)}
}
The documentation can be found here. I believe this was just added in grails 2.+

Ruby way to group anagrams in string array

I implemented a function to group anagrams.
In a nutshell:
input: ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', scream']
output: [["cars", "racs", "scar"], ["four"], ["for"], ["potatoes"],["creams", "scream"]]
I would like to know if there is a better way to do this.
I really think I used too much repetition statements: until, select,
delete_if.
Is there any way to combine the select and delete_if statement? That
means, can selected items be automatically deleted?
Code:
def group_anagrams(words)
array = []
until words.empty?
word = words.first
array.push( words.select { |match| word.downcase.chars.sort.join.eql?(match.downcase.chars.sort.join ) } )
words.delete_if { |match| word.downcase.chars.sort.join.eql?(match.downcase.chars.sort.join ) }
end
array
end
Thanks in advance,
Like that:
a = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams', 'scream']
a.group_by { |element| element.downcase.chars.sort }.values
Output is:
[["cars", "racs", "scar"], ["for"], ["potatoes"], ["four"], ["creams", "scream"]]
If you want to you can turn this one-liner to a method of course.
You could use the partition function instead of select, implemented in Enumerable. It splits the entries within the array according to the decision-function into two arrays.
def group_anagrams(words)
array = []
until words.empty?
word = words.first
delta, words = words.partition { |match| word.downcase.chars.sort.join.eql?(match.downcase.chars.sort.join ) } )
array += delta
end
array
end
(untested)

How to sort Domain-Objects with attribute with type JodaTime / DateTime in grails 1.3.7?

I'm working on a small event calendar and i want to sort the events by start time!
I'm using JodaTime Plugin in grails for the startTime attribute. ( http://www.grails.org/JodaTime+Plugin )
So, how can i sort with this datatype? This does not work:
def sortedEvents = events.asList().sort({ a, b -> a.startTime <=> b.startTime } as Comparator)
I hope you can help me!
Thanks,
whitenexx
/EDIT/
This is the code where i'm getting the events:
def getEventsNext(Location location) {
def events = location.events.findAll { it.endTime >= new DateTime() }
def sortedEvents = events.sort{it.startTime}
System.out.println(sortedEvents); //test
return sortedEvents
}
In /event/list action everything works fine with g:sortableColumn (sorting by startTime):
Try this:
def sortedEvents = events.asList().sort{it.startTime}
To reverse the sorting order, use:
def sortedEvents = events.asList().sort{-it.startTime}
FYI, Groovy adds this sort() method to Collection so you can remove asList() from the code above if events is already a Collection.
Try overriding the compareTo method in your domain classes.
For example,
int compareTo(obj) {
startTime.compareTo(obj.startTime)
}
Edit
Sort your events like so:
def sortedEvents = events.sort{e1,e2-> e1.startTime.compareTo(2.startTime)}
Or as suggested by #Don, the groovier equivalent
def sortedEvents = events.sort{e1,e2-> e1.startTime <=> e2.startTime}
Try
def events = location.events.findAll { it.endTime.isAfterNow() }
def sortedEvents = events.sort{it.startTime.toDate()}
JavaDoc for isAfterNow()

What is an elegant way to replace an element of an array based on a match criteria?

I am using the following logic to update a list item based on a criteria.
def update_orders_list(order)
#orders.delete_if{|o| o.id == order.id}
#orders << order
end
Ideally, I would have preferred these approaches:
array.find_and_replace(obj) { |o| conditon }
OR
idx = array.find_index_of { |o| condition }
array[idx] = obj
Is there a better way?
array.map { |o| if condition(o) then obj else o }
maybe?
As of 1.8.7, Array#index accepts a block. So your last example should work just fine with a minor tweak.
idx = array.index { |o| condition }
array[idx] = obj

Resources