I have dictionary
Output = [a:2, c:13, b:5, z:'Test']
I use for loop as follows
for(i in Output){
println(Output[i.key]);
}
it is result.
2
13
5
Test
but I expect result (reverse).
Test
5
13
2
Could you please help me?
What you have is not a "dictionary" (this is not Python), but a Map.
The order of its entries is not defined it is just a mapping key to value without any ordering. The order you get is (pseudo-)random and can not be depended upon.
Btw. the more Groovy way for producing the output would be to not use a for-loop, but e. g.
[a:2, c:13, b:5, z:'Test'].values().each { println it }
If you want to have an order, you need a list instead of a map, e. g. like a list of maps as in
[[a:2], [c:13], [b:5], [z:'Test']].reverse().collectMany { it.values() }.each { println it }
or a list of lists as in
[['a', 2], ['c', 13], ['b', 5], ['z', 'Test']].reverse().collect { it[1] }.each { println it }
or maybe this list of maps which probably would be the cleanest of these solutions
[[key:'a', value:2], [key:'c', value:13], [key:'b', value:5], [key:'z', value:'Test']].reverse().collect { it.value }.each { println it }
Related
So I was tasked to make a function using python, that returns how many values there is in a dictionary that ONLY contains lists. An example of such a dictionary would be:
animals = { 'a': ['alpaca','ardvark'], 'b': ['baboon'], 'c': ['coati']}
The values inside the list also count towards the total values returned from the function, which means that it has to return 4. This is the function I made:
def how_many(aDict):
'''
aDict: A dictionary, where all the values are lists.
returns: int, how many values are in the dictionary.
'''
numValues = 0;
while aDict != {}:
tupKeyValue = aDict.popitem();
List = tupKeyValue[1];
numValues += len(List);
return numValues;
So I was wondering if there was a way to pop the last value of a dictionary without popitem() which extracts the key-value pair. Just trying to make it as simple as possible.
Since you are not using the dictionaries keys maybe you could just use values() along with sum():
def how_many(d):
return sum(len(v) for v in d.values())
animals = {'a': ['alpaca', 'ardvark'], 'b': ['baboon'], 'c': ['coati']}
print(how_many(animals))
Output:
4
Let's say I've got three lists with objects
List<String> list1, list2, list3
What is the best way to do check whether any of them is not empty and do some action?
So far I came up with
if ([list1, list2, list3].any()) {
// do some action
}
But is there a way to omit if block at all?
I don't think there can be anything better than
if (list1 || list2 || list3) {
}
You want some kind of NotEmptyPredicate(l1, l2, l3).ifMatch { println 'hi' }, but it does not exist in standard library. Creating one is not worth.
One objective part of your question is about omitting the if block. This answer pertains to that. I don't recommend this for production code, nor do I claim this is the best way, which is subjective.
Generally, if statements can be "hidden" by using maps. (The context is a new static method on List, via Groovy's meta-programming):
List.metaClass.static.ifNotEmpty = { List<String>... lists ->
def resultMap = [:]
resultMap[true] = { Closure c -> c.call() }
resultMap[false] = { Closure c -> }
return resultMap[lists.any()]
}
Here are example usages... See this Q&A to understand the unusual syntax of ({ })
List<String> list1, list2, list3
list1 = []
list2 = null
list3 = []
list3 << "HELLO"
List.ifNotEmpty(list1, list2, list3) ({ println "test 1" })
list1 = []
list2 = null
list3 = []
List.ifNotEmpty(list1, list2, list3) ({ println "should not see this" })
I am trying to get the set values from closure in groovy:
myList(1, 2, 3).any { it > 2 }
myList(1, 2, 3).find { it > 2 }
So not able to figure out, which one to use and better.
any returns boolean - true if any of the elements on the list matches the closure condition, while find returns first element that meets the criteria in closure being passed.
If you need to know if there're elements matching certain criteria, use any, if you need only a single element (the first one) use, find, if you need all the elements that matches the closure passed use findAll.
Example:
assert [1, 2, 3].any { it > 1 }
assert [1, 2, 3].find { it > 1 } == 2
assert [1, 2, 3].findAll { it > 1 } == [2, 3]
Assuming we have a flat list of lists in groovy, like the following:
[[id: 1,title: A],[id: 2, title: B],[id: 3, title: C]]
What is the fastest way to transform it in a hierarchy where B is children to A and C is Children to B?
I can do this with iterations, but since groovy is so creative, I am wondering if there is a smarter way.
You can do this sort of thing if you don't mind mutating your original list and its elements:
def list = [[id: 1,title: 'A'],[id: 2, title: 'B'],[id: 3, title: 'C']]
list.inject( [:] ) { prev, next ->
if( prev ) {
prev.child = next
}
next
}
assert list.head() == [id:1, title:'A', child:[id:2, title:'B', child:[id:3, title:'C']]]
I have a collection of maps that looks something like this:
def list = [
[key1: 'ABC', key2: 3, value: 1.01],
[key1: 'ABC', key2: 4, value: 1.02],
[key1: 'ABC', key2: 4, value: 1.03],
[key1: 'DEF', key2: 3, value: 1.04]]
I'm trying to get a result that looks like this that groups and sums up the values for the unique key1 and key2 values and results in a hierarchy.
['ABC':[[key2: 2, value: 1.01]
[key2: 4, value: 2.05]], //note values are added
'DEF':[[key2: 3, value: 1.04]]
]
There are many examples of mapping routines that have one key, but what is the best way to fold these when using more than one key?
One solution I thought of was to use groupby to get the list grouped by the first key. The problem there is the combine or reduce must then be run on the sub list of each element:
list.parallel
.map{it}
.groupBy{it.key1}
at this point I want to reduce on the .value() of the grouped maps which I can't really do within the chain
I also tried to use combine, which works a bit like the examples here. However it looks like if combine gets a map back, it wants to combine it further.
def result = list.parallel
.map{[it.key1, it]}
.combine({-> [:]}) { map, v -> println "$map - $v = ${v.getClass()}"
map[v.key2] = map[v.key2]?:0 + v.value
map
}
Then there is the option to just reduce on the maps, but the reduce routine then becomes a pretty complicated beast of combining nested maps. So I'm wondering if there is something simpler, or should I just run a reduce routine to combine the complex maps.
list.parallel
.map{[(it.key1):it]}
.reduce([:]) { a, b ->
complexMapCombiner(a, b)
}
So here's a solution that works, but is less elegant than I'd like. If anyone has something better please post an answer.
#Grab(group='org.codehaus.gpars', module='gpars', version='1.0.0')
import static groovyx.gpars.GParsPool.*
def list = [
[key1: 'ABC', key2: 3, value: 1.01],
[key1: 'ABC', key2: 4, value: 1.02],
[key1: 'ABC', key2: 4, value: 1.03],
[key1: 'DEF', key2: 3, value: 1.04]]
withPool {
def mapInner = { entrylist ->
withPool{
entrylist.getParallel()
.map{[it.key2, it.value]}
.combine(0) {acc, v -> acc + v}.getParallel()
.map{[key2: it.key, value: it.value]}.collection
}
}
//for dealing with bug when only 1 list item
def collectSingle = { entrylist ->
def first = entrylist[0]
return [[key2:(first.key2), value:first.value]]
}
def result = list.parallel
.groupBy{it.key1}.getParallel()
.map{ [(it.key) : (it.value?.size())>1?mapInner.call(it.value):collectSingle.call(it.value) ] }
.reduce([:]) {a, b -> a + b}
println "result = $result"
}