groovy: convert string (which is a list) to a Groovy List - grails

import groovy.json.JsonSlurper
def ver = "['a', 'b', 'c']"
def jsonSlurper = new JsonSlurper()
def ver_list = jsonSlurper.parseText(ver)
println ver_list
This is what I'm doing. I want to iterate over ver_list. And it seems difficult to find a solution for it.
This is the error when I print ver_list:
Caught: groovy.json.JsonException: Unable to determine the current character, it is not a string, number, array, or object
The current character read is ''' with an int value of 39
Unable to determine the current character, it is not a string, number, array, or object
line number 1
index number 1
['a', 'b', 'c']
.^
groovy.json.JsonException: Unable to determine the current character, it is not a string, number, array, or object
The current character read is ''' with an int value of 39
Unable to determine the current character, it is not a string, number, array, or object
line number 1
index number 1
['a', 'b', 'c']

the valid json strings must be double-quoted.
so change in your code this line and it should work:
def ver = '["a", "b", "c"]'
however if you need to parse not a valid json you could try LAX parser.
then even the following string could be parsed
import groovy.json.JsonSlurper
import groovy.json.JsonParserType
def ver = "[a, 'b', 001]"
def jsonSlurper = new JsonSlurper().setType( JsonParserType.LAX )
def ver_list = jsonSlurper.parseText(ver)
println ver_list

Related

The return statement not working as expected

So I am trying to write a function which edits a dataframe in place- drops a column and adds another column to it. Within the function I am getting the expected output, but when I am trying to print the dataframe outside the function, it is still printing the original values:
import pandas as pd
import numpy as np
def login_table(id_name_verified, id_password):
"""
:param id_name_verified: (DataFrame) DataFrame with columns: Id, Login, Verified.
:param id_password: (numpy.array) Two-dimensional NumPy array where each element
is an array that contains: Id and Password
:returns: (None) The function should modify id_name_verified DataFrame in-place.
It should not return anything.
"""
password= pd.DataFrame(data=id_password[:,1],columns=["Password"])
id_name_verified = id_name_verified.join(password["Password"])
id_name_verified.drop("Verified",axis=1,inplace=True)
return id_name_verified
id_name_verified = pd.DataFrame([[1, "JohnDoe", True], [2, "AnnFranklin", False]], columns=["Id", "Login", "Verified"])
global id_name_verified
id_password = np.array([[1, 987340123], [2, 187031122]], np.int32)
login_table(id_name_verified, id_password)
print(id_name_verified)
The last print statement is still printing:
Id Login Verified
0 1 JohnDoe True
1 2 AnnFranklin False
What am I missing? I am new to python. Please help!
So instead of the join I had to use the loc function to add the password to the id_name_verified dataframe:
def login_table(id_name_verified, id_password):
password = pd.DataFrame(id_password, columns=["Id", "Password"])
id_name_verified.loc[:, 'Password'] = password['Password']
id_name_verified.drop("Verified",axis=1,inplace=True)
return None
This did the trick.

How to compute each cell of a line in an array with Ruby on Rails 5.2?

While importing from an excel file to a database, I need to format a hierarchy so it appears with leading zeros:
10.1.1.4 must be transformed into 1.010.001.001.004
I tried to iterate through and concatenate the elements:
record.hierarchy = spreadsheet.cell(i,2).split('.').each do |t|
index = index || '1.'
index = index + '.' + (((t.to_i + 1000).to_s).last(3))
end
which actually returns and array of ["10", "1", "1", "4"], not computed. I would expect this to return the last evaluated value: index
I tried to compute it directly inside the array:
record.hierarchy = '1.' + (((spreadsheet.cell(i,2).split('.').each).to_i + 1000).to_s).last(3).join('.')
which raises an undefined method to_i for enumerator.
Can someone explain me how to structure and solve this computation?
Thanks
Use #rjust.
'10.1.1.4'.split('.').map { |l| l.rjust(3, '0') }.join('.')
Your first solution uses assignment with #each. #each will not return modified array.
It is not necessary to convert the string to an array, modify the elements of the array and then join the array back into a string. The string can be modified directly using String#gsub.
str = '10.1.1.4'
('1.' + str).gsub(/(?<=\.)\d+/) { |s| sprintf("%03d", s.to_i) }
#=> "1.010.001.001.004"
See Kernel#sprintf.
(?<=\.) is positive lookbehind that requires the matched digits to be preceded by a period. I've assumed the string is known to contain between one and three digits before and after each period.
You can try different function for leading zeroes and inject to not set default value inside the loop
record.hierarchy = spreadsheet.cell(i,2).split('.').inject('1') do |result, t|
result + '.' + t.rjust(3, '0')
end

How to read column value using grails excel import plugin?

I am using Grails excel import plugin to import an excel file.
static Map propertyConfigurationMap = [
name:([expectedType: ExcelImportService.PROPERTY_TYPE_STRING, defaultValue:null]),
age:([expectedType: ExcelImportService.PROPERTY_TYPE_INT, defaultValue:0])]
static Map CONFIG_BOOK_COLUMN_MAP = [
sheet:'Sheet1',
startRow: 1,
columnMap: [
//Col, Map-Key
'A':'name',
'B':'age',
]
]
I am able to retrieve the array list by using the code snippet:
def usersList = excelImportService.columns(workbook, CONFIG_USER_COLUMN_MAP)
which results in
[[name: Mark, age: 25], [name: Jhon, age: 46], [name: Anil, age: 62], [name: Steve, age: 32]]
And also I'm able to read each record say [name: Mark, age: 25] by using usersList.get(0)
How do I read the each column value?
I know I can read something like this
String[] row = usersList.get(0)
for (String s : row)
println s
I wonder is there any thing that plugin supports so that I can read column value directly rather manipulating it to get the desired result.
Your usersList is basically a List<Map<String, Object>> (list of maps). You can read a column using the name you gave it in the config. In your example, you named column A name and column B age. So using your iteration example as a basis, you can read each column like this:
Map row = usersList.get(0)
for(Map.Entry entry : row) {
println entry.value
}
Groovy makes this easier to do with Object.each(Closure):
row.each { key, value ->
println value
}
If you want to read a specific column value, here are a few ways to do it:
println row.name // One
println row['name'] // Two
println row.getAt('name') // Three
Hint: These all end up calling row.getAt('name')

How can I trim all elements in a list using Groovy?

I need trim all elements in a list in groovy or grails?
what is the best solution
Assuming it is a list of strings and you want to trim each string, you can do it using the spread operator (*.)
list = [" abc ", " xyz "]
list*.trim()
You can use the collect method or the spread operator to create a new list with the trimmed elements:
def strs = ['a', ' b', ' ']
assert strs.collect { it.trim() } == ['a', 'b', '']
assert strs*.trim() == ['a', 'b', '']
In those cases, the original list isn't modified. If you want to trim the strings in place, you'll need to iterate through the list with an index:
for (i in 0..<strs.size()) {
strs[i] = strs[i].trim()
}

how to sort groovy list values based on some criteria

I have one scenario to sort the values based domain class property. This property may acept all numeric and alphanumeric values in the format XXX-1.
def res= Book.listOrderByName()
or
def res = Book.findAll("from Book order by name")
Giving the same result and result is displaying first numbers latter alphanumeric values.
My problem is :
these values are sorted before -.
for example i have AB-1,AB-2,...AB-12.
The result is displayed as AB-1,AB-10.AB-11,AB-2,AB-3,..AB-9
I have result like:
[18001,18002,2,300,3901,42,9,AB-1,AB-10,AB-2,AB-21,AB-9]
It should display the value as:
[2,9,42,300,3901,18001,18002,AB-1,AB-2,AB-9,AB-10,AB-21]
Run this in the Groovy console:
List sort(list) {
list.sort {a, b ->
a.class == b.class ? a <=> b : a instanceof Integer ? -1 : 1
}
}
// Test the sort function
def list = [18001,18002,2,300,3901,42,9,'AB-1','AB-10','AB-2','AB-21','AB-9']
assert sort(list) == [2, 9, 42, 300, 3901, 18001, 18002, 'AB-1', 'AB-10', 'AB-2', 'AB-21', 'AB-9']

Resources