Deleting a key-value pair from hash (RUBY) - ruby

movies = {
StarWars: 4.8,
Divergent: 4.7
}
print movies
This code returns a hash:
{:StarWars=>4.8, :Divergent=>4.7}
When I try to delete a key-value pair and print movies again:
movies = {
StarWars: 4.8,
Divergent: 4.7
}
movies = movies.delete("Divergent".to_sym)
print movies
I get :
4.7
How do I delete a key-value pair, so that after I ask to print the contents of movies hash I get :
{:StarWars=>4.8}

Hash#delete returns the value of provided key, movies.delete("Divergent".to_sym) returns 4.7, and you reassign it to movies, now movies is 4.7.
So you could just delete and don't reassign:
movies.delete("Divergent".to_sym)
print movies # => {:StarWars=>4.8}

Related

Order list in recycler view, Android Studio, Kotlin

I am trying to order the results downloaded from Firestore.
I download and print the result and they are out of order, after ordering them I bring them again and they print in order of date, but the result in the recycler view doesn't update.
This is the code I use to order the list, originally it is an array list of hash map but I convert it to a mutable list so I can order it and then back to an array list.
val newList = messagesInfo.sortedWith(compareBy {
it.dateC }).toMutableList()
messagesInfo = newList as ArrayList<MessagesPost>
println("Tony the date new list array is $messagesInfo")
messagesAdapter.notifyDataSetChanged()
I have figured this out.
by moving my submit list down under the reassignment of the array.
val newList = messagesInfo.sortedWith(compareBy {
it.dateC }).toMutableList().reversed()
messagesInfo = newList as ArrayList<MessagesPost>
messagesAdapter.submitList(messagesInfo)
messagesAdapter.notifyDataSetChanged()

How to get a SQL like GROUP BY using Apache Pig?

I have the following input called movieUserTagFltr:
(260,{(260,starwars),(260,George Lucas),(260,sci-fi),(260,cult classic),(260,Science Fiction),(260,classic),(260,supernatural powers),(260,nerdy),(260,Science Fiction),(260,critically acclaimed),(260,Science Fiction),(260,action),(260,script),(260,"imaginary world),(260,space),(260,Science Fiction),(260,"space epic),(260,Syfy),(260,series),(260,classic sci-fi),(260,space adventure),(260,jedi),(260,awesome soundtrack),(260,awesome),(260,coming of age)})
(858,{(858,Katso Sanna!)})
(924,{(924,slow),(924,boring)})
(1256,{(1256,Marx Brothers)})
it follows the schema: (movieId:int, tags:bag{(movieId:int, tag:cararray),...})
Basically the first number represents a movie id, and the subsequent bag holds all the keywords associated with that movie. I would like to group those key words in such way that I would have an output something like this:
(260,{(1,starwars),(1,George Lucas),(1,sci-fi),(1,cult classic),(4,Science Fiction),(1,classic),(1,supernatural powers),(1,nerdy),(1,critically acclaimed),(1,action),(1,script),(1,"imaginary world),(1,space),(1,"space epic),(1,Syfy),(1,series),(1,classic sci-fi),(1,space adventure),(1,jedi),(1,awesome soundtrack),(1,awesome),(1,coming of age)})
(858,{(1,Katso Sanna!)})
(924,{(1,slow),(1,boring)})
(1256,{(1,Marx Brothers)})
Note that the tag Science Fiction has appeared 4 times for the movie with id 260. Using the GROUP BY and COUNT I manged to count the distinct keywords for each movie using the following script:
sum = FOREACH group_data {
unique_tags = DISTINCT movieUserTagFltr.tags::tag;
GENERATE group, COUNT(unique_tags) as tag;
};
But that only returns a global count, I want a local count. So the logic of what I was thinking was:
result = iterate over each tuple of group_data {
generate a tuple with $0, and a bag with {
foreach distinct tag that group_data has on it's $1 variable do {
generate a tuple like: (tag_name, count of how many times that tag appeared on $1)
}
}
}
You can flatten out your original input so that each movieID and tag are their own record. Then group by movieID and tag to get a count for each combination. Finally, group by movieID so that you end up with a bag of tags and counts for each movie.
Let's say you start with movieUserTagFltr with the schema you described:
A = FOREACH movieUserTagFltr GENERATE FLATTEN(tags) AS (movieID, tag);
B = GROUP A BY (movieID, tag);
C = FOREACH B GENERATE
FLATTEN(group) AS (movieID, tag),
COUNT(A) AS movie_tag_count;
D = GROUP C BY movieID;
Your final schema is:
D: {group: int,C: {(movieID: int,tag: chararray,movie_tag_count: long)}}

Get value from Ruby hash

I want to use this Ruby code to get fixed values:
FIXED_COUNTRY_TO_PHONE = [
{ country: 'FI', customer_phone: '+4672345678' },
{ country: 'SE', customer_phone: '+4672311178' }
].freeze
I tries this: FIXED_COUNTRY_TO_PHONE[country] but I don't get the customer_phone value. How I can get the value?
Hash is within an array so use this
p FIXED_COUNTRY_TO_PHONE.map{|x| x[:country]}
output
["FI", "SE"]
If you want to take the first country then
p FIXED_COUNTRY_TO_PHONE.first[:country]
If you want to take the last country then
p FIXED_COUNTRY_TO_PHONE.last[:country]
Getting the country code according to country
p FIXED_COUNTRY_TO_PHONE.detect{|x| x[:country].eql?'FI'}[:customer_phone]

Ruby: Hash w/ Arrays, Returning Associated Key If Value Is In Array

New to Ruby and have run out of ideas. I have an array of books that I would like to 1) Shelve 2) Find which shelf it is on 3) Remove it from the associated shelf if found. For brevity I have an array of 6 books. Each shelf contains 5 books.
library_catalog = [ "Book1", "Book2", "Book3", "Book4", "Book5", "Book6" ]
shelves = Hash.new(0)
catalog_slice = library_catalog.each_slice(5).to_a
count = 1
catalog_slice.each do | x |
shelves.merge!(count=>x)
count+=1
end
From this I know have a Hash w/ arrays as such
{1=>["Book1", "Book2", "Book3", "Book4", "Book5"], 2=>["Book6"]}
This is where I'm having trouble traversing the hash to find a match inside the array and return the key(shelf). If I have title = "Book1" and I am trying to match and return 1, how would I go about this?
I think this should work.
shelves.select { |k,v| v.include?("Book1")}.keys.first
selected the hashes that have a value equal to the title you are looking for (in this case "Book1")
get the keys for these hashes as an array
get the first entry in the array.
to remove the Book from the shelf try this:
key = shelves.select { |k,v| v.include?("Book1")}.keys.first
shelves[key].reject! { |b| b == "Book1" }
get a reference to the array and then reject the entry you want to remove

increment value in a hash

I have a bunch of posts which have category tags in them.
I am trying to find out how many times each category has been used.
I'm using rails with mongodb, BUT I don't think I need to be getting the occurrence of categories from the db, so the mongo part shouldn't matter.
This is what I have so far
#recent_posts = current_user.recent_posts #returns the 10 most recent posts
#categories_hash = {'tech' => 0, 'world' => 0, 'entertainment' => 0, 'sports' => 0}
#recent_posts do |cat|
cat.categories.each do |addCat|
#categories_hash.increment(addCat) #obviously this is where I'm having problems
end
end
end
the structure of the post is
{"_id" : ObjectId("idnumber"), "created_at" : "Tue Aug 03...", "categories" :["world", "sports"], "message" : "the text of the post", "poster_id" : ObjectId("idOfUserPoster"), "voters" : []}
I'm open to suggestions on how else to get the count of categories, but I will want to get the count of voters eventually, so it seems to me the best way is to increment the categories_hash, and then add the voters.length, but one thing at a time, i'm just trying to figure out how to increment values in the hash.
If you aren't familiar with map/reduce and you don't care about scaling up, this is not as elegant as map/reduce, but should be sufficient for small sites:
#categories_hash = Hash.new(0)
current_user.recent_posts.each do |post|
post.categories.each do |category|
#categories_hash[category] += 1
end
end
If you're using mongodb, an elegant way to aggregate tag usage would be, to use a map/reduce operation. Mongodb supports map/reduce operations using JavaScript code. Map/reduce runs on the db server(s), i.e. your application does not have to retrieve and analyze every document (which wouldn't scale well for large collections).
As an example, here are the map and reduce functions I use in my blog on the articles collection to aggregate the usage of tags (which is used to build the tag cloud in the sidebar). Documents in the articles collection have a key named 'tags' which holds an array of strings (the tags)
The map function simply emits 1 on every used tag to count it:
function () {
if (this.tags) {
this.tags.forEach(function (tag) {
emit(tag, 1);
});
}
}
The reduce function sums up the counts:
function (key, values) {
var total = 0;
values.forEach(function (v) {
total += v;
});
return total;
}
As a result, the database returns a hash that has a key for every tag and its usage count as a value. E.g.:
{ 'rails' => 5, 'ruby' => 12, 'linux' => 3 }

Resources