Filter an array in Ruby - ruby

In Ruby, I have a hash like below. How can I get the "name" of the "tag" where the tag_type is "LocationTag"? In this case, the returned value would be 'singapore'.
Is the best method just to do:
location = nil
tags.each do |t|
if t["tag_type"] == "LocationTag"
location = t.name
end
end
or does ruby have a better method for filtering hashes?
{
tags: [
{
"id": 81410,
"tag_type": "SkillTag",
"name": "angular.js",
"display_name": "Angular.JS",
"angellist_url": "https:\/\/angel.co\/angular-js"
},
{
"id": 84038,
"tag_type": "SkillTag",
"name": "bootstrap",
"display_name": "Bootstrap",
"angellist_url": "https:\/\/angel.co\/bootstrap"
},
{
"id": 1682,
"tag_type": "LocationTag",
"name": "singapore",
"display_name": "Singapore",
"angellist_url": "https:\/\/angel.co\/singapore"
},
{
"id": 14726,
"tag_type": "RoleTag",
"name": "developer",
"display_name": "Developer",
"angellist_url": "https:\/\/angel.co\/developer"
}
]
}

This will get you the first hit:
tags.detect{|tag| tag['tag_type'] == 'LocationTag'}['name']
This will give you all hits as an array
tags.select{|tag| tag['tag_type'] == 'LocationTag'}.map{|t| t['name']}
Check out the docs for Ruby#Enumerable for more details.
Ruby#Enumerable:detect
Ruby#Enumerable:select
(Thanks #PaulRichter for the comment... it's a nice clarifying addition to the post)

You can use find to stop the iteration once you've found a result:
location = tags.find { |t| t["name"] if t["tag_type"] == "LocationTag" }
Mind the errors that got fixed in the above: t.name and = "LocationTag".

Related

Delete existing Records if they are not in sent array Rails 5 API

I need help on how to delete records that exist in the DB but not in array sent in a request;
My Array:
[
{ "id": "509",
"name": "Motions move great",
"body": "",
"subtopics": [
{
"title": "Tywan",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
},
{
"title": "Transportations Gracious",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
},
{
"title": "Transportation part",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
}
]
},
{
"name": "Motions kkk",
"body": "",
"subtopics": [
{
"title": "Transportations",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
}
]
}
]
Below is my implementation: where am going wrong?
#topics = #course.topics.map{|m| m.id()}
#delete= #topics
puts #delete
if Topic.where.not('id IN(?)', #topics).any?
#topics.each do |topic|
topic.destroy
end
end
it's not clear to me where, in your code, you pick the ids sent in the array you showed before... so I'm assuming like this:
objects_sent = [
{ "id": "509",
"name": "Motions move great",
"body": "",
"subtopics": [
{
"title": "Tywan",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
},
{
"title": "Transportations Gracious",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
},
{
"title": "Transportation part",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
}
]
},
{
"name": "Motions kkk",
"body": "",
"subtopics": [
{
"title": "Transportations",
"url_path": "https://ugonline.s3.amazonaws.com/resources/6ca0fd64-8214-4788-8967-b650722ac97f/WhatsApp+Audio+2021-09-24+at+13.57.34.mpeg"
}
]
}
]
since you have your array like this, the only information you need to query on database is the ids (also, assuming the id's in the array are the id's on database, otherwise it wouldn't make sense). You can get them like this:
sent_ids = objects_sent.map{|o| o['id'].to_i}
Also, it seems to me that, for the code you showed, you want to destroy them based on a specific course. There would be 2 ways to do that. First, using the relationship (I prefer like this one):
#course.topics.where.not(id: sent_ids).destroy_all
Or you can do the query directly on the Topic model, but passing the course_id param:
Topic.where(course_id: #course.id).where.not(id: sent_ids).destroy_all
ActiveRecord is smart enough to mount that query correctly in both ways. Give it a test and see which works better for you

Sorting an array of objects based on object property

I have an array like so:
[
{
"name": "aabb",
"commit": {
"id": "1",
"message": "aabb ",
"committed_date": "2018-04-04T15:11:04.000+05:30",
"committer_name": "ak",
"committer_email": "ak#ak.in"
},
"protected": false
},
{
"name": "aacc",
"commit": {
"id": "2",
"message": "aacc ",
"committed_date": "2018-02-04T15:11:04.000+05:30",
"committer_name": "ak",
"committer_email": "ak#ak.in"
},
"protected": false
},
{
"name": "aadd",
"commit": {
"id": "3",
"message": "aadd ",
"committed_date": "2018-04-01T15:11:04.000+05:30",
"committer_name": "ak",
"committer_email": "ak#ak.in"
},
"protected": false
}
]
I need to sort this array based on committed_date. How do I do that?
Do I have to loop and write a custom sorting function or does Ruby offers something out-of-box?
Using sort_by
array.sort_by {|obj| obj.attribute}
Or more concise
array.sort_by(&:attribute)
In your case
array.sort_by {|obj| obj[:commit][:committed_date]}

Transferring JSON Data into an array using ruby

This is my JSON code
{
"jobs": [
{
"id": 1,
"title": "Software Developer",
"applicants": [
{
"id": 1,
"name": "Rich Hickey",
"tags": ["clojure", "java", "immutability", "datomic", "transducers"]
},
{
"id": 2,
"name": "Guido van Rossum",
"tags": ["python", "google", "bdfl", "drop-box"]
}
]
},
{
"id": 2,
"title": "Software Architect",
"applicants": [
{
"id": 42,
"name": "Rob Pike",
"tags": ["plan-9", "TUPE", "go", "google", "sawzall"]
},
{
"id": 2,
"name": "Guido van Rossum",
"tags": ["python", "google", "bdfl", "drop-box"]
},
{
"id": 1337,
"name": "Jeffrey Dean",
"tags": ["spanner", "BigTable", "MapReduce", "deep learning", "massive clusters"]
}
]
}
]
}
I want to put the list of "Jobs" in an array using ruby.
I have the following code so far.
require 'json'
file = File.read(filepath)
data_hash = JSON.parse(file)
How do I iterate on the data_hash and chose what information I want and place it in an array?
You can use Array#each because data_hash['jobs'] contains an array of jobs:
data_hash['jobs'].each {|job| ... }
Like this,
arr = Array.new
data_hash.each { |job|
arr.insert(job['name'])
}
use Array#map for shorter code
data_hash['jobs'].map do |job|
# Do whatever you want with the job here
properties = %w(title applicants)
job.select{ |key| properties.include?(key) }
end

Iterate through JSON respone Facebook Graph

Im trying to iterate through a returned response from the Facebook Graph api
def get_feed
uri = URI(FACEBOOK_URL)
response = HTTParty.get(uri)
results = JSON.parse(response.body)['data']
puts formatted_data(results)
end
def formatted_data(results)
return unless results
formatted = results['data'].each do |d|
unless d.nil?
{
message: d['message'],
}
end
formatted.delete_if {|x| x.nil?}
end
end
The response is very large so here is a snippet if it helps
{
"data": [
{
"id": "197958940234297_827831980580320",
"from": {
"category": "Amateur sports team",
"category_list": [
{
"id": "189018581118681",
"name": "Sports Club"
},
{
"id": "139721016091877",
"name": "Outdoor Recreation"
},
{
"id": "109615542448700",
"name": "Physical Fitness"
}
],
"name": "Varsity Vandals",
"id": "197958940234297"
},
"to": {
"data": [
{
"id": "668983363",
"name": "Heather Walker"
},
{
"id": "638195502",
"name": "Emma Williams"
},
{
"id": "1286337937",
"name": "Becky Williams"
}
]
},
"with_tags": {
"data": [
{
"id": "668983363",
"name": "Heather Walker"
},
{
"id": "638195502",
"name": "Emma Williams"
},
{
"id": "1286337937",
"name": "Becky Williams"
}
]
},
"message": "Great turnout for the women's intro session today. Cool to have a women's game and a men's game running side by side. Touch is for all.",
"picture": "https://fbcdn-photos-f-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/1507550_827829843913867_410211203232735862_s.jpg",
"link": "https://www.facebook.com/photo.php?fbid=827829843913867&set=pcb.827831980580320&type=1&relevant_count=2",
"icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif",
"actions": [
{
"name": "Comment",
"link": "https://www.facebook.com/197958940234297/posts/827831980580320"
},
{
"name": "Like",
"link": "https://www.facebook.com/197958940234297/posts/827831980580320"
}
],
"privacy": {
"value": ""
},
I am getting an error
TypeError: no implicit conversion of String into Integer
At the moment i would just like to pull out all the Messages from the JSON object...Am i handling the extraction correctly
Any help appreciated
Thanks
I tried you code, I change you require is move formatted.delete_if {|x| x.nil?} out of loop, like following, as formatted will be nil inside the loop.
def formatted_data(results)
return unless results
formatted = results['data'].each do |d|
unless d.nil?
{
message: d['message'],
}
end
end
formatted.delete_if {|x| x.nil?}
end
are you sure your not using the data key twice?
results = JSON.parse(response.body)['data'] in main method and formatted = results['data'].each in your formatted_data method?
Thinking maybe?
def def formatted_data(results)
return unless results
results['data'].map {|m| {message: m['message']} }.compact
end
I'd do this:
def get_feed
uri = URI(FACEBOOK_URL)
response = HTTParty.get(uri)
messages = format_data(response)
for message in messages do
puts message
end
end
def format_data(response, new_data = [])
if response.present?
results = JSON.parse(response)
for result in results do
new_data << result[:data][:message] if result[:data][:message].present?
end
return new_data #-> array of messages
end
end

How to add key/value pair in hash with ruby laungage

I am using ruby 2.0.0, At present i have one demo.json file with following hash values:
{
"users":
{
"#jon" :
{
"name": "pradeep",
"Email": "pradeep#yahoo.com",
"area": "#jon",
"location": "#newyork"
},
"#smith" :
{
"name": "Smith",
"Email": "Joe#yahoo.com",
"area": "#smith",
"location": "#lverginia"
}
}
}
now i am taking json values in object using following codes:
require 'json'
json = File.read('demo.json')
obj = JSON.parse(json)
here #jon and #smith is usernames, Now i wants to take usernames via keyboard inputs and than all the other values inside of #jon with same keyboard.
Suppose i have one new user #david and his other values are like:
"name": "pradeep",
"Email": "pradeep#yahoo.com",
"area": "#jon",
"location": "#newyork"
i wants to add this in above demo.json file without remove other values, Any idea how can i do?
I tried to do this in this way:
obj["users"]
But as i got username via input so i cant hard code username after user key on "obj" object, Hope this make sense..
Read this JSON also .
I'd do as below :
require 'json'
json = JSON.parse(File.read("test.json"))
new_information_arry = ["users", "name", "Email", "area", "location"].map do |elem|
puts "please give the value of #{elem}"
[elem,gets.chomp]
end
new_information_hash = Hash[new_information_arry[1..-1]]
json['users'][new_information_arry.first.last] = new_information_hash
File.write("outputfile.json",JSON.pretty_generate(json))
I put the below content to my file 'test.json' :
{
"users":
{
"#jon" :
{
"name": "pradeep",
"Email": "pradeep#yahoo.com",
"area": "#jon",
"location": "#newyork"
},
"#smith" :
{
"name": "Smith",
"Email": "Joe#yahoo.com",
"area": "#smith",
"location": "#lverginia"
}
}
}
Then I ran the above code as below :
please give the value of users
#david
please give the value of name
pradeep
please give the value of Email
pradeep#yahoo.com
please give the value of area
#jon
please give the value of location
#newyor
And now my output file outputfile.json contains :
{
"users": {
"#jon": {
"name": "pradeep",
"Email": "pradeep#yahoo.com",
"area": "#jon",
"location": "#newyork"
},
"#smith": {
"name": "Smith",
"Email": "Joe#yahoo.com",
"area": "#smith",
"location": "#lverginia"
},
"#david": {
"name": "pradeep",
"Email": "pradeep#yahoo.com",
"area": "#jon",
"location": "#newyor"
}
}
}

Resources