Convert sql.GroovyRowResult with two columns to map - groovy

I have a groovy GroovyRowResult (using sql.rows) with two columns. The first column has a group by in the sql, so it will always be unique.
Now I would like to convert the whole result into a map, which contains the first column value as the key and the second column value as the value. I know that I can do this with each for every single row (see below), but was wondering if there is a better aproeach. The only thing I've found is entrySet(), which did not work. Error is:
Message: No signature of method:
java.util.ArrayList.entrySet() is applicable for argument types: () values: [])
So my each row way would be:
def myMap = [:]
result.each {
myMap.put(it.colum1, it.column2)
}
Another alternative would be, to make the query in a way that will return me a map with the first column as the key and the second as the value (or the whole row as the value). Kind of Zend frameworks fetchAssoc() method.

You could do:
def myMap = result.collectEntries {
[ it.column1, it.column2 ]
}

Related

Python: (partial) matching elements of a list to DataFrame columns, returning entry of a different column

I am a beginner in python and have encountered the following problem: I have a long list of strings (I took 3 now for the example):
ENSEMBL_IDs = ['ENSG00000040608',
'ENSG00000070371',
'ENSG00000070413']
which are partial matches of the data in column 0 of my DataFrame genes_df (first 3 entries shown):
genes_list = (['ENSG00000040608.28', 'RTN4R'],
['ENSG00000070371.91', 'CLTCL1'],
['ENSG00000070413.17', 'DGCR2'])
genes_df = pd.DataFrame(genes_list)
The task I want to perform is conceptually not that difficult: I want to compare each element of ENSEMBL_IDs to genes_df.iloc[:,0] (which are partial matches: each element of ENSEMBL_IDs is contained within column 0 of genes_df, as outlined above). If the element of EMSEMBL_IDs matches the element in genes_df.iloc[:,0] (which it does, apart from the extra numbers after the period ".XX" ), I want to return the "corresponding" value that is stored in the first column of the genes_df Dataframe: the actual gene name, 'RTN4R' as an example.
I want to store these in a list. So, in the end, I would be left with a list like follows:
`genenames = ['RTN4R', 'CLTCL1', 'DGCR2']`
Some info that might be helpful: all of the entries in ENSEMBL_IDs are unique, and all of them are for sure contained in column 0 of genes_df.
I think I am looking for something along the lines of:
`genenames = []
for i in ENSEMBL_IDs:
if i in genes_df.iloc[:,0]:
genenames.append(# corresponding value in genes_df.iloc[:,1])`
I am sorry if the question has been asked before; I kept looking and was not able to find a solution that was applicable to my problem.
Thank you for your help!
Thanks also for the edit, English is not my first language, so the improvements were insightful.
You can get rid of the part after the dot (with str.extract or str.replace) before matching the values with isin:
m = genes_df[0].str.extract('([^.]+)', expand=False).isin(ENSEMBL_IDs)
# or
m = genes_df[0].str.replace('\..*$', '', regex=True).isin(ENSEMBL_IDs)
out = genes_df.loc[m, 1].tolist()
Or use a regex with str.match:
pattern = '|'.join(ENSEMBL_IDs)
m = genes_df[0].str.match(pattern)
out = genes_df.loc[m, 1].tolist()
Output: ['RTN4R', 'CLTCL1', 'DGCR2']

I need an Integer but its a string with a comma

I'm using sqlite3 and trying to get the oid by using the title of the row and then trying to use that oid to update a column in my table.
allOID is a tuple, and when I print it i get this:
>>> <class 'tuple'>
>>> [(1,)]
I'm trying to get the integer out of this tuple but the comma is throwing it off and I can't seem to get it.
Here is all of the code being used currently:
c.execute("""SELECT oid FROM books
WHERE title = :title""",
{
'title': title
})
allOID = c.fetchall()
print(type(allOID[0]))
print(allOID)
c.execute("SELECT * FROM books")
c.execute("""UPDATE books SET
rented = :rented
WHERE oid = :oid""",
{
'rented': rentedVar,
'oid': allOID[0]
})
any help and comments are greatly appreciated!
The comma just indicates that it is a tuple with a single element.
Access it using allOID[0][0].
allOID[0] gets you the tuple out of the list of results, going one level further with allOID[0][0] gets you the first element of the tuple.
For more info, see the docs:
Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective.

groovy iterate through list of key and value

I have this list:
service_name_status=[a-service=INSTALL, b-service=UPGRADE, C-service=UPGRADE, D-service=INSTALL]
And I need to iterate through this list so the first element will be the value of a parameter called "SERVICE_NAME" and the second element will be the value of a parameter called "HELM_COMMAND",
after asserting those values to the parameters I will run my command that uses those parameters and then continue the next items on the list which should replace the values of the parameters with items 3 and 4 and so on.
So what I am looking for is something like that:
def service_name_status=[a-service=INSTALL, b-service=UPGRADE, C-service=UPGRADE, D-service=INSTALL]
def SERVICE_NAME
def HELM_COMMAND
for(x in service_name_status){
SERVICE_NAME=x(0,2,4,6,8...)
HELM_COMMAND=x(1,3,5,7,9...)
println SERVICE_NAME=$SERVICE_NAME
println HELM_COMMAND=$HELM_COMMAND
}
the output should be:
SERVICE_NAME=a-service
HELM_COMMAND=INSTALL
SERVICE_NAME=b-service
HELM_COMMAND=UPGRADE
SERVICE_NAME=c-service
HELM_COMMAND=UPGRADE
SERVICE_NAME=d-service
HELM_COMMAND=INSTALL
and so on...
I couldn't find anything that takes any other element in groovy, any help will be appreciated.
The collection you want is a Map, not a List.
Take note of the quotes in the map, the values are strings so you need the quotes or it won't work. You may have to change that at the source where your data comes from.
I kept your all caps variable names so you will feel at home, but they are not the convention.
Note the list iteration with .each(key, value)
This will work:
Map service_name_status = ['a-service':'INSTALL', 'b-service':'UPGRADE', 'C-service':'UPGRADE', 'D-service':'INSTALL']
service_name_status.each {SERVICE_NAME, HELM_COMMAND ->
println "SERVICE_NAME=${SERVICE_NAME}"
println "HELM_COMMAND=${HELM_COMMAND}"
}
EDIT:
The following can be used to convert that to a map. Be careful, the replaceAll part is fragile and depends on the data to always look the same.
//assuming you can have it in a string like this
String st = "[a-service=INSTALL, b-service=UPGRADE, C-service=UPGRADE, D-service=INSTALL]"
//this part is dependent on format
String mpStr = st.replaceAll(/\[/, "['")
.replaceAll(/=/, "':'")
.replaceAll(/]/, "']")
.replaceAll(/, /, "', '")
println mpStr
//convert the properly formatted string to a map
Map mp = evaluate(mpStr)
assert mp instanceof java.util.LinkedHashMap

Filter the list generated by a Gremlin traversal and Groovy

I'm doing the following traversal:
g.V().has('Transfer','eventName','Airdrop').as('t1').
outE('sent_to').
inV().dedup().as('a2').
inE('sent_from').
outV().as('t2').
where('t1',eq('t2')).by('address').
outE('sent_to').
inV().as('a3').
select('a3','a2').
by('accountId').toList().groupBy { it.a3 }.collectEntries { [(it.key): [a2 : it.value.a2]]};
So as you can see I'm basically doing a traversal and at the end I'm using groovy with collectEntries to aggregate the results like I need them, which is aggregated by a3 in this case. The results look like this:
==>0xfe43502662ce2adf86d9d49f25a27d65c70a709d={a2=[0x99feb505a8ed9976cf19e757a9536117e6cdc5ba, 0x22019ad32ea3adabae68003bdefd099d7e5e3886]}
(This is GOOD, because the number of values in a2 is at least 2)
==>0x129e0131ea3cc16fe5252d7280bd1258f629f20f={a2=[0xf7958fad496d15cf9fd9e54c0012504f4fdb96ff]}
(This is NOT GOOD, I want to return in my list only those combinations where there are at lest 2 values for a2)
I have tried using filters and an additional where step in the traversal itself but I haven't been able to do it. I'm not sure if this is something I should skip using Groovy in my last line. Any help or orientation would be very much appreciated
I don't think you need to drop into Groovy to get the answer you want. It would be preferable to do this all in Gremlin especially since you intend to filter results which could yield some performance benefit. Gremlin has it's own group() step as well as methods for filtering the resulting Map:
g.V().has('Transfer','eventName','Airdrop').as('t1').
out('sent_to').
dedup().as('a2').
in('sent_from').as('t2').
where('t1',eq('t2')).by('address').
out('sent_to').inV().as('a3').
select('a3','a2').
by('accountId').
group().
by('a3').
by('a2').
unfold().
where(select(values).limit(local,2).count(local).is(gte(2)))
The idea is to build your Map with group() then deconstruct it to entries with unfold(). You the filter each entry with where() by selecting the values of the entry, which is a List of "a2" then counting the items locally in that List. I use limit(local,2) to avoid unnecessary iteration beyond 2 since the filter is gte(2).
The easiest way to do this is with findAll { }.
.groupBy { it.a3 }
.findAll { it.value.a2.size() > 1 }
.collectEntries { [(it.key): [a2: it.value.a2]] }
if some a2 are null, then value.a2 also evaluates to null and filters the results without the need for explicit nullchecks

How to match values in arrays and match result against key/val pair

I'm using Groovy.
I've got two sets of data. The first is an array of site codes and the second is a key/val map of some JSON data.
I need to loop through the list of site codes and match them to key in the map. Once it finds a match it needs to return the corresponding map val.
The map array looks like this:
list = ["WSM-3572", "WSM-0301","WSM-10153"]
A keypair looks like this:
{id=3dd9794a-d148-4f74-a297-cefe22d05cfd, name=Nedbank Mall of Africa(WSM-3572)},{id=8fb57fda-8bdf-4aef-8d50-f3bf8d2235e1, name=Caffe Rossini (WSM-3432)},
{id=bd12b3ef-b72f-4211-8987-2e0c6f1f688d, name=Steers Welkom (WSM-4502)},
So in the above case we should run through the list and when it gets to WSM-3572 it should find it and match the site code in the name: Nedbank Mall of Africa(WSM-3572) and then return id=3dd9794a-d148-4f74-a297-cefe22d05cfd.
I hope this all makes sense and thanks in advance
Assuming you've loaded your json into a map with JsonSlurper, something like
list.each { code ->
println "$code = " + json.find { it ->
it.name.contains "($it)"
}?.id
}
Should do it.
Not at a computer, but that should be close

Resources