In Kotlin, if you want to use the element of the forEach, you can use the it keyword. So now I wonder that what should I do if I have a forEach inside forEach like that:
list.forEach {
val parent = it
it.forEach {
// `it` now become the element of the parent.
}
}
I think that defines a new variable only for the naming convention be so stupid. Have any other solution for this problem?
it is just a default param name inside of all single argument closures. You could specify param name by yourself:
collection.forEach { customName ->
...
}
In addition to the correct answer above by Artyom, I'd like to say that if you only care for the inner it, you can simply ignore the name overloading.
See:
>> var a = "abc"
>> a?.let { it[2]?.let { it } }
c
The value returned is the most inner "it". "it", there, refers to the outermost "it[2]", that is, the character 'c' from the string "abc".
Now, if you want to access the outermost "it", you should name it something else like Artyom says. The code below is equivalent to the code above, but it allows you to refer to "outerIt" from the outer 'let' block in the innermost 'let' block, if that's what you need.
>> var a = "abc"
>> a?.let { outerIt -> outerIt[2]?.let { it } }
c
This way, if you need to refer to the outermost it, you can. For example:
>> var a = "abc"
>> a?.let { outerIt -> outerIt[2]?.let { "${outerIt[1]} $it" } }
b c
If you don't need to refer to the outermost "it", I'd personally prefer the first construct because it is terser.
Related
I want to use a key insde an anonymous table from within that same table, like so:
loadstring( [[return {
a = "One",
b = a.." two"
}]] )
From my perspective, this should return the following table:
{ a = "One", b = "One two" }
However, it just returns nil.
Is this possible to do, and how?
As the other answer said, you can't reference a key in a table that is being constructed, but you can use a variable to hold the value you want to reference several times:
local a = "One"
local t = { a = a, b = a.." two" }
No, you can't do that. At the point you are using a the table has not been constructed. Lua looks for a global variable a, which is why you get nil.
If you want to refer to keys in a table they must be defined first.
local t = { a = 'One' }
t.b = t.a..' two'
I'm trying to create an object oriented implementation in Lua, for example:
Parent = {
ChildVariable = "Hello",
ChildFunction = function ()
print(Parent.ChildVariable)
end
}
What I would like is rather than doing Parent.ChildVariable I can do ChildVariable instead; it is in the table so I thought must be some way to access it.
Parent = {
ChildVariable = "Hello",
ChildFunction = function(self)
print(self.ChildVariable)
end
}
Parent:ChildFunction()
Lua has a special construct for that: the colon operator.
The two following lines are equivalent:
tbl.func(tbl)
and
tbl:func()
I have two very similar methods in Grails, something like "calculate statistics by os" and "calculate statistics by browser" - effectively both prepare some things, then run a similar query on the DB, then do things with the results. The only part where the methods differ is the query they run in the middle of my method -
def summary = c.list {
eq('browser', Browser.get(1)) // OR eq('os', OS.get(1))
between('date', dates.start, dates.end)
}
It occurred to me that the ideal way to refactor it would be to pass in the first line of the closure as a method parameter. Like
doStats (Closure query) {
...
def summary = c.list {
query
between('date', dates.start, dates.end)
}
}
I tried this but "query" gets ignored. I tried query() instead but then the query clause is executed where defined, so this doesn't work either. I suppose I could just pass the whole closure as a parameter but that seems wrong - the query might also get more complicated in future.
Anyone have any better ideas?
I found leftShift operator useful for composing closure from two separate ones. What you can do is:
Closure a = { /*...*/ }
Closure b = { /*...*/ }
Closure c = a << b
Take a look at this example:
def criteria = {
projection Projections.distinct(Projections.property('id'))
and {
eq 'owner.id', userDetails.id
if (filter.groupId) {
eq 'group.id', filter.groupId
}
}
}
List<Long> ids = Contact.createCriteria().list(criteria << {
maxResults filter.max
firstResult filter.offset
})
Integer totalCount = Contact.createCriteria().count(criteria)
What you can see here is that I'm creating a criteria for listing ant counting GORM objects. Criterias for both cases are almost the same, but for listing purposes I also need to include limit and offset from command object.
You're using the criteria DSL which might be different than plain groovy closures.
To do what you're asking, you can use the method described here -
http://mrhaki.blogspot.com/2010/06/grails-goodness-refactoring-criteria.html
and put your query in to private method.
The more elegant solution for this is to use named queries in grails -
http://grails.org/doc/latest/ref/Domain%20Classes/namedQueries.html
Look at the
recentPublicationsWithBookInTitle {
// calls to other named queries…
recentPublications()
publicationsWithBookInTitle()
}
example -
Not sure about with the Grails Criteria builder, but with other builders, you can do something like:
doStats (Closure query) {
def summary = c.list {
query( it )
between('date', dates.start, dates.end)
}
}
And call this via:
def f = { criteria ->
criteria.eq( 'browser', Browser.get( 1 ) )
}
doStats( f )
If not, you're probably best looking at named queries like tomas says
I am trying to use recursion in groovy to traverse a tree relationship. The below code runs one cycle, upto childNodes && recurClosure(childNodes ) , but doesn't call the closure recurClosure again. At that instant childNodes had two objects (array list) same type as root.
In the code, recurClosure is defined and calls with a list of objects (root). It then iterates through each element and fines the child nodes (uses grails dsl for this).If the childNodes is not null, it recursively calls the parent method.
Should I break it up, or what is wrong?
def parentval
def root = Domain.list()
def recurClosure
recurClosure = {inroot ->
inroot.each {
returnList << it
parentval = it
childNodes = Domain.withCriteria {
eq('parent', parentval )
}
}
childNodes && recurClosure(childNodes )
}(root)
return returnList
}
thanks in advance.
Update: The following exception is noted
ERROR [2010-06-24 08:20:04,742] [groovy.grails.web.errors.GrailsExceptionResolver] Cannot invoke method call() on null object
java.lang.NullPointerException: Cannot invoke method call() on null object
at com.bsr.test.DomainService$_closure2_closure7.doCall(com.bsr.test.DomainService:68)
at com.bsr.test.DomainService$_closure2.doCall(com.bsr.test.DomainService:58)
at com.bsr.test.DomainController$_closure3.doCall(DomainController.groovy:45)
at com.bsr.test.DomainController$_closure3.doCall(DomainController.groovy)
at org.apache.shiro.web.servlet.ShiroFilter.executeChain(ShiroFilter.java:687)
at org.apache.shiro.web.servlet.ShiroFilter.doFilterInternal(ShiroFilter.java:616)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81)
at java.lang.Thread.run(Thread.java:619)
Update 2: Now trying Daniel's suggestion.
{ inroot ->
inroot.each {
returnList << it
parentval = it
childNodes = Domain.withCriteria {
eq('parent', parentval )
}
if(childNodes)
call(childNodes)
}
/*if(childNodes)
call(childNodes)*/
}(root)
In the above implementation, root is an arraylist, The inner closure takes each element out of it and recursively calls the anonymous closure. When I moved the 'call' inside the each closure, it doesn't call the outer anonymous closure, but the inroot.each {} itself. So, I get an error
ERROR [2010-06-24 08:47:46,438] [groovy.grails.web.errors.GrailsExceptionResolver] instance not of expected entity type: java.util.ArrayList is not a: com.bsr.test.Domain
I see a blog post about how to name the closure through 'this' > I'll update my finding.. thanks
Update 3: The way to call the outer closure is owner.call(childNodes)
The problem is, that by
recurClosure = {
[...]
}(root)
you don't assign the closure to recurClosure, but rather the return value of its invocation! Thus, of course, you can't call the closure via recurClosure()...
Two possible solutions:
First define the closure, and then call it separately, as air_blob suggested:
def recurClosure = {
[...]
}
recurClosure(root)
Use the implicit call() function for recursion. This way you can even work with an anonymous closure. IMHO a very nice way to implement recursion in Groovy:
{ inroot ->
inroot.each {
returnList << it
parentval = it
childNodes = Domain.withCriteria {
eq('parent', parentval )
}
}
if(childNodes)
call(childNodes)
}(root)
Two more comments on your code:
You may want to declare returnList: def returnList = []
While childNodes && recurClosure(childNodes ) may do what you want, it's much more readable to sacrifice one more char and spell out the if.. ;-)
Don't you want to recursively call your closure inside the each?
Another (higher-level) remark on your code: If the parents and their children are of the same type (Domain), won't Domain.list() actually return all children, too? Is there really a need for traversing the tree manually?
Do you get any exceptions?
Have you tried invoking it separately like this:
def recurClosure
recurClosure = {inroot ->
[... stuff ...]
}
recurClosure(root)
What exactly do you want to do in this line:
childNodes && recurClosure(childNodes )
I'm browsing sample asp.net code in an MVC project and need a better understanding of the => operator. Plugging => into search engines is non-helpful.
thx
The => syntax creates lambda expressions, which are small functions.
For example, the line
Func<int, int> myFunc = i => 2 * i;
declares a variable of type Func<int, int> (a delegate that takes one integer and returns another one), and assigns it to a lambda expressions that takes a parameter called i (the compiler automatically figures out that i is an int) and returns 2 * i.
Yo can search it as lambda. See here http://msdn.microsoft.com/en-us/library/bb397687.aspx
The => operator, as has been mentioned, represents a lambda expression. This is short-hand for an anonymous delegate. Here is practical example:
If you want to filter all Person objects in a collection to return only Male people, the Where() extension method requires a Func delegate you could create a named delegate like this:
Func<Person, bool> isMale = delegate(Person peep) { return peep.Gender == "male"; };
var men = from p in peeps.Where(isMale)
select p;
Or you could use an anonymous delegate like this:
var women = from p in peeps.Where(delegate(Person peep) { return peep.Gender != "male"; })
select p;
The lambda allows you to declare the anonymous delegate using a short-hand, like this:
var women = from p in peeps.Where(x => x.Gender != "male")
select p;
Notice the correspondence between delegate(Person peep) and x, and between 'return peep.Gender != "male"and 'x.Gender != "male".