I'm trying to sort a map in Groovy that has maps as value. I want to iterate over the map and print out the values sorted by lastName and firstName values. So in the following example:
def m =
[1:[firstName:'John', lastName:'Smith', email:'john#john.com'],
2:[firstName:'Amy', lastName:'Madigan', email:'amy#amy.com'],
3:[firstName:'Lucy', lastName:'B', email:'lucy#lucy.com'],
4:[firstName:'Ella', lastName:'B', email:'ella#ella.com'],
5:[firstName:'Pete', lastName:'Dog', email:'pete#dog.com']]
the desired results would be:
[firstName:'Ella', lastName:'B', email:'ella#ella.com']
[firstName:'Lucy', lastName:'B', email:'lucy#lucy.com']
[firstName:'Pete', lastName:'Dog', email:'pete#dog.com']
[firstName:'Amy', lastName:'Madigan', email:'amy#amy.com']
[firstName:'John', lastName:'Smith', email:'john#john.com']
I've tried m.sort{it.value.lastName&&it.value.firstName} and m.sort{[it.value.lastName, it.value.firstName]}. Sorting by m.sort{it.value.lastName} works but does not sort by firstName.
Can anybody help with this, much appreciated, thanks!
This should do it:
m.values().sort { a, b ->
a.lastName <=> b.lastName ?: a.firstName <=> b.firstName
}
Related
I need select from tarantool all datat by two values from one space.
How i can perform request to tarantool like in mysql?
select from aaa where a=1a22cadbdb or a=7f626e0123
Now i can make two requests:
box.space.logs:select({'1a22cadbdb'})
box.space.logs:select({'7f626e0123'})
but i don't know how to merge result into one ;(
Following code merge field[0] to lua table
a = box.space.logs:select({'1a22cadbdb'})
b = box.space.logs:select({'7f626e0123'})
c = { field_1 = a[0], field_2 = b[0] }
The select return tuple or tuples so you can extract value via [].
More details about select: http://tarantool.org/doc/book/box/box_index.html?highlight=select#lua-function.index_object.select
More details about tuple: http://tarantool.org/doc/book/box/box_tuple.html?highlight=tuple#lua-module.box.tuple
Nowadays Tarantool allows you to retrieve via SQL, for example box.execute([[select from "aaa" where "a"='1a22cadbdb' or "a"='7f626e0123';]]). You have to add the field names and types of aaa before doing this, with the format() function.
For me this work fine, but need make check for return from first select:
local res = {}
for k, v in pairs (box.space.email:select({email})[1]) do
if type(v) == 'string' then
table.insert(res, box.space.logs:select({v})[1])
end
end
I'm trying to make a function to sort a table after a value inside it. Is there no functions for this already in lua? I can't seem to find one.
local table2 = {};
for i, v in pairs(table) do
if( table[i].field > table[i+1].field ) then
this is how far I got before I thought that it wouldn't work.
Can someone help me?
The question is not quite clear, but if you mean to sort values in a table that may have some complex value, you can do this by using a "custom" search function:
local t = {
{field = 2},
{field = 1},
}
table.sort(t, function(t1, t2)
return t1.field < t2.field
end)
print(t[1].field, t[2].field) -- prints 1, 2
See sorting table by value for related details.
I have a given list of data :
def given = [
[Country:'Japan',Flag:'Yes',Event:'New Year'],
[Country:'china',Flag:'No',Event:'Spring Festival'],
[Country:'uk',Flag:'No',Event:'National Holiday'],
[Country:'us',Flag:'Yes',Event:'Labour Day'],
[Country:'us',Flag:'Yes',Event:'New Year'],
[Country:'uk',Flag:'Yes',Event:'Memorial Day']
]
I can sort using groovy sort method :
given = given.collect().sort { a, b ->
a.Flag <=> b.Flag ?: a.Event <=> b.Event
}
but, how would i do it if the sort by is mentioned by user and stored in separate list like
eg : def sortOrder = ["Country","Flag"], Here sort Order is dynamic that is users choice : ["Country","Flag"] / ["Country","Flag","Event"] or none. How can i write sort method so that it takes my dynamic arguments in closure ?
Assuming you have your custom order in a variable order, try
given.sort { a, b ->
order.inject(0) { o, e ->
o ?: a[e] <=> b[e]
}
}
One way would be to iterate the sortorder and use findResult to get the "ufo" results. The ugly part about this, is that findResults does not use groovy truth and sort needs an int, so some elvis action is needed to. e.g.
def given = [[Country:'Japan',Flag:'Yes',Event:'New Year'],
[Country:'china',Flag:'No',Event:'Spring Festival'],
[Country:'uk',Flag:'No',Event:'National Holiday'],
[Country:'us',Flag:'Yes',Event:'Labour Day'],
[Country:'us',Flag:'Yes',Event:'New Year'],
[Country:'uk',Flag:'Yes',Event:'Memorial Day']]
def sortorder = ['Flag', 'Event']
assert given.sort{ a,b ->
sortorder.findResult{ a[it] <=> b[it] ?: null } ?: 0
}.first()==[Country:'uk', Flag:'No', Event:'National Holiday']
I have raw data in bag:
{(id,35821),(lang,en-US),(pf_1,us)}
{(path,/ybe/wer),(id,23481),(lang,en-US),(intl,us),(pf_1,yahoo),(pf_3,test)}
{(id,98234),(lang,ir-IL),(pf_1,il),(pf_2,werasdf|dfsas)}
How could I extract the tuples whose column 1 matches id and pf_*?
The output I want:
{(id,35821),(pf_1,us)}
{(id,23481),(pf_1,yahoo),(pf_3,test)}
{(id,98234),(pf_1,il),(pf_2,werasdf|dfsas)}
Any suggestion would be appreciated. Thanks!
In order to process the inner bag (a bag in a format like OUTER_BAG: {INNER_BAG: {(e:int)}}) you are going to have to use a nested FOREACH. This will allow you to preform operations over the tuples in the inner bag.
For example, you are going to want to do something like:
-- A: {inner_bag: {(val1: chararray, val2: chararray)}}
B = FOREACH A {
filtered_bags = FILTER inner_bag BY val1 matches '^(id|pf_).*' ;
GENERATE filtered_bags ;
}
In the Sequel ORM for Ruby, the Dataset class has an all method which produces an Array of row hashes: each row is a Hash with column names as keys.
For example, given a table T:
a b c
--------------
0 22 "Abe"
1 35 "Betty"
2 58 "Chris"
then:
ds = DB['select a, b, c from T']
ah = ds.all # Array of row Hashes
should produce:
[{"a":0,"b":22,"c":"Abe"},{"a":1,"b":35,"c":"Betty"},{"a":2,"b":58,"c":"Chris"}]
Is there a way built in to Sequel to instead produce an Array of row Arrays, where each row is an array of only the values in each row in the order specified in the query? Sort of how select_rows works in ActiveRecord? Something like this:
aa = ds.rows # Array of row Arrays
which would produce:
[[0,22,"Abe"],[1,35,"Betty"],[2,58,"Chris"]]
Note: the expression:
aa = ds.map { |h| h.values }
produces an array of arrays, but the order of values in the rows is NOT guaranteed to match the order requested in the original query. In this example, aa might look like:
[["Abe",0,22],["Betty",1,35],["Chris",2,58]]
Old versions of Sequel (pre 2.0) had the ability in some adapters to return arrays instead of hashes. But it caused numerous issues, nobody used it, and I didn't want to maintain it, so it was removed. If you really want arrays, you need to drop down to the connection level and use a connection specific method:
DB.synchronize do |conn|
rows = conn.exec('SQL Here') # Hypothetical example code
end
The actual code you need will depend on the adapter you are using.
DB[:table].where().select_map(:id)
If you want just an array of array of values...
DB['select * from T'].map { |h| h.values }
seems to work
UPDATE given the updated requirement of the column order matching the query order...
cols= [:a, :c, :b]
DB[:T].select{cols}.collect{ |h| cols.collect {|c| h[c]}}
not very pretty but guaranteed order is the same as the select order.
There does not appear to be a builtin to do this.
You could make a request for the feature.
I haven't yet found a built-in method to return an array of row arrays where the values in the row arrays are ordered by the column order in the original query. The following function does* although I suspect an internal method could be more effecient:
def rows( ds )
ret = []
column_keys = ds.columns # guaranteed to match query order?
ds.all { |row_hash|
row_array = []
column_keys.map { |column_key| row_array << row_hash[column_key] }
ret << row_array
}
ret
end
*This function depends on the order of the array returned by Dataset.columns. If this order is undefined, then this rows function isn't very useful.
have you tried this?
ds = DB['select a, b, c from T'].to_a
not sure it it works but give it a shot.