Iterate through a child map in a for loop in groovy - for-loop

Let us assume I have a map like below which contains another map (child map) within it. I like to print the child map as individual rows for each key.
def map =[
1: [
[name:"Jerry", age: 42, city: "New York"],
[name:"Long", age: 25, city: "New York"]
],
2: [
[name:"Dustin", age: 29, city: "New York"],
[name:"Bob", age: 34, city: "New York"]
]
]
Currently, I iterate through the parent map, and am able to print the names. But, that is not actually what I want. I wanted to see if I can atleast iterate through the parent map. I do not see errors so far.
for(allentries in map){
loggerApi.info("${allentries.key}: ${allentries.value.name}") // this prints [Jerry, Long] for key 1 & [Dustin, Bob] for key 2
loggerApi.info("${allentries.key}: ${allentries.value.age}")
loggerApi.info("${allentries.key}: ${allentries.value.city}")
}
Can you please let me know what I should add to the above code to see individual rows like these:
Name Age City
Jerry 42 New York
Long 25 New York
Dustin 29 New York
Bob 34 New York
Appreciate.
Thank you.
Br,
Noor.

Assuming you got the input structure wrong in the question, and you have a list of maps inside each value in map, you can just iterate through them in an internal loop
​def map =[
1: [
[name:"Jerry", age: 42, city: "New York"],
[name:"Long", age: 25, city: "New York"]
],
2: [
[name:"Dustin", age: 29, city: "New York"],
[name:"Bob", age: 34, city: "New York"]
]
]
map.each { key, value ->
value.each { submap ->
println "$key $submap.name $submap.age $submap.city"
// Or with no prefixing number:
// println "$submap.name $submap.age $submap.city"
}
}

Related

Sort a list of dictionaries by a specific key within a nested list of dictionaries

I have a list of dictionaries with each entry having the following structure
{
"id": 0,
"type": "notification",
"name": "jane doe",
"loc": {
"lat": 38.8239,
"long": 104.7001
},
"data": [
{
"type": "test",
"time": "Fri Aug 13 09:17:16 2021",
"df": 80000000,
"db": 1000000,
"tp": 92
},
{
"type": "real",
"time": "Sat Aug 14 09:21:30 2021",
"df": 70000000,
"db": 2000000,
"tp:": 97
}
]
}
I need to be able to sort this list by any of these keys: name, type, time, tp and return it in memory.
I understand how to sort by the top level keys sorted(json_list, key=lambda k:k['name']) or even nested keys. For instance by lat sorted(json_list, key=lambda k:k['loc']['lat'])
so currently I have a function that works for the case when sorting by name.
def sort_by(self, param, rev=False):
if param == NAME:
self.json_list = sorted(self.json_list, key=lambda k: k[param], reverse=rev)
else:
# need help here
I'm having trouble sorting by type, time, and tp. Notice the data key is also a list of dictionaries. I would like to leverage existing methods built into the standard lib if possible. I can provide more clarification if necessary
Update:
def sort_by(self, param, rev=False):
if param == NAME:
self.json_list = sorted(self.json_list, key=lambda k: k[param], reverse=rev)
else:
self.json_list = sorted(self.json_list, key=lambda k: k['data'][0][param], reverse=rev)
return self.json_list
This works fine if there is only one item in the data list
If json_list[i]['data'] (for each i) only contains one dict, then the following should work; otherwise modifications are required.
sorted(json_list, key = lambda k: (
k['name'], k['data']['type'], k['data']['time'], k['data']['tp']
))

How to generate a distinct average of lots of data in Pig Latin?

I have a large data set of rental listings that I want to generate the average price for each city based on the number of bedrooms. I have the following types of rows:
{( city: 'New York', num_bedrooms: 1, price: 1000.00 ),
( city: 'New York', num_bedrooms: 2, price: 2000.00 ),
( city: 'New York', num_bedrooms: 1, price: 2000.00 ),
( city: 'Chicago', num_bedrooms: 1, price: 4000.00 ),
( city: 'Chicago', num_bedrooms: 1, price: 1500.00 )}
Using Pig, I want to get results in the following format:
{( city: 'New York', 1: 1500.00, 2: 2000.00),
( city: 'Chicago', 1: 2750.00 )}
Alternatively, I could deal with this too:
{( city: 'New York', num_bedrooms: 1, price: 1500.00),
( city: 'New York', num_bedrooms: 2, price: 2000.00),
( city: 'Chicago', num_bedrooms: 1, price: 2750.00 )}
My plan is to create bar charts using this data with the number of bedrooms along the X axis, and the price on the Y axis for a given city. I have been able to group by city and number of bedrooms and then average that, but I don't know how to put the data in the format I want. So far this is what I have:
D = GROUP blah BY (city, num_bedrooms);
C = FOREACH D GENERATE blah.city, blah.num_bedrooms, AVG(blah.price);
However this causes the city and num_bedrooms to be repeated for each time they appear!
Input :
New York,1,1000.00
New York,2,2000.00
New York,1,2000.00
Chicago,1,4000.00
Chicago,1,1500.00
Approach 1 :
Pig Script :
rental_data = LOAD 'rental_data.csv' USING PigStorage(',') AS (city:chararray, num_bedrooms: long, price:double);
rental_data_grp_city = GROUP rental_data BY (city);
rental_kpi = FOREACH rental_data_grp_city {
one_bed_room = FILTER rental_data BY num_bedrooms==1;
two_bed_room = FILTER rental_data BY num_bedrooms==2;
GENERATE group AS city, AVG(one_bed_room.price) AS one_bed_price, AVG(two_bed_room.price) AS tow_bed_price;
};
Output : DUMP rental_kpi :
(Chicago,2750.0,)
(New York,1500.0,2000.0)
Approach 2 :
Pig Script :
rental_data = LOAD 'rental_data.csv' USING PigStorage(',') AS (city:chararray, num_bedrooms: long, price:double);
rental_data_grp_city = GROUP rental_data BY (city,num_bedrooms);
rental_kpi = FOREACH rental_data_grp_city {
prices_bag = rental_data.price;
GENERATE group.city AS city, group.num_bedrooms AS num_bedrooms, AVG(prices_bag) AS price;
}
Output : DUMP rental_kpi :
(Chicago,1,2750.0)
(New York,2,2000.0)
(New York,1,1500.0)

ActiveRecord: Unique by attribute

I am trying to filter ActiveRecord_AssociationRelations to be unique by parent id.
So, I'd like a list like this:
[#<Message id: 25, posted_by_id: 3, posted_at: "2014-10-30 06:02:47", parent_id: 20, content: "This is a comment", created_at: "2014-10-30 06:02:47", updated_at: "2014-10-30 06:02:47">,
#<Message id: 23, posted_by_id: 3, posted_at: "2014-10-28 16:11:02", parent_id: 20, content: "This is another comment", created_at: "2014-10-28 16:11:02", updated_at: "2014-10-28 16:11:02">]}
to return this:
[#<Message id: 25, posted_by_id: 3, posted_at: "2014-10-30 06:02:47", parent_id: 20, content: "This is a comment", created_at: "2014-10-30 06:02:47", updated_at: "2014-10-30 06:02:47">]
I've tried various techniques including:
#messages.uniq(&:parent_id) # returns the same list (with duplicate parent_ids)
#messages.select(:parent_id).distinct # returns [#<Message id: nil, parent_id: 20>]
and uniq_by has been removed from Rails 4.1.
Have you tried
group(:parent_id)
It sounds to me like that is what you are after. This does return the first entry with the given parent_id. If you want the last entry you will have to reorder the result in a subquery and then use the group.
For me in Rails 3.2 & Postgresql, Foo.group(:bar) works on simple queries but gives me an error if I have any where clauses on there, for instance
irb> Message.where(receiver_id: 434).group(:sender_id)
=> PG::GroupingError: ERROR: column "messages.id" must appear in the
GROUP BY clause or be used in an aggregate function
I ended up specifying an SQL 'DISTINCT ON' clause to select. In a Message class I have the following scope:
scope :latest_from_each_sender, -> { order("sender_id ASC, created_at DESC").select('DISTINCT ON ("sender_id") *') }
Usage:
irb> Message.where(receiver_id: 434).latest_from_each_sender

Get Unique contents from Ruby Hash

I have a Hash #estate:
[#<Estate id: 1, Name: "Thane ", Address: "Thane St.", created_at: "2013-06-21 16:40:50", updated_at: "2013-06-21 16:40:50", user_id: 2, asset_file_name: "DSC02358.JPG", asset_content_type: "image/jpeg", asset_file_size: 5520613, asset_updated_at: "2013-06-21 16:40:49", Mgmt: "abc">,
#<Estate id: 2, Name: "Mumbai", Address: "Mumbai St.", created_at: "2013-06-21 19:13:59", updated_at: "2013-06-21 19:14:28", user_id: 2, asset_file_name: "DSC02359.JPG", asset_content_type: "image/jpeg", asset_file_size: 5085580, asset_updated_at: "2013-06-21 19:13:57", Mgmt: "abc">]
Is it possible to make new Hash with unique values according to the user_id: 2, because currently 2 elements have the user_id same i.e 2, I just want it once in the hash, what should I do ?
It seems to be something like a has_many relation between User model and Estate model, right? If I understood you correctly, than you need in fact to group your Estate by user_id:
PostgreSQL:
Estate.select('DISTINCT ON (user_id) *').all
MySQL:
Estate.group(:user_id).all
P.S. I'd not recommend to select all records from a database and then process them with Ruby as databases handle operations with data in much more efficient way.
Here is an sample example to get you a good start:
h = [ { a: 2, b: 3}, { a: 2, c: 3 } ]
h.uniq { |i| i[:a] }
# => [{:a=>2, :b=>3}]

CouchDB combine sorted documents to one document

I have 2 documents:
{ path: "/monster/green", name: "Green monster", age: 105, timeline: 1 }
{ path: "/monster/green" name: "Really Green Monster", timeline: 2 }
The question:
How can I create a CouchDB view, where the documents are sorted by 'timeline' and the result is a combination of them:
{ path: "/monster/green", name: "Really Green Monster", age: 105 }
You can easily create a view which will give you the following output for key="/monster/green" :
{[
{"key":"/monster/green", "value":{"name": "Green monster", "age": 105},
{"key":"/monster/green", "value":{"name": "Really Green monster"}
]}
Except the format, this is really similar to the data you wanted.
If you really need to change the format, you can define a list on top of your view.

Resources