I'm using MagicalRecord to import json object to Core Data. I have a list of persons with firstName and lastName attributes. This works fine. each person has a list of degrees that is a simple array of strings. I would like to map this list of string to my Degree core data entity and map the string to the e.g. Degree.name attribute
[
{
"firstName": "ba",
"lastName": "bar",
"degrees": [
"MSc",
"BSc"
]
},
{
"firstName": "Fo",
"lastName": "foo",
"degrees": [
"MSc"
]
}
]
I tried using a empty mappedKeyName on the name attribute as described here but it does not work.
Related
I'm attempting to decode multiple JSON URLs into a class. Since I'm using an API, I have no control over the fact that the JSON data is split into two URLs. Here is the problem statement:
I have a class called Student
JSON URL student_info.json contains a dictionary with all students and the Student instance constants A, and B.
JSON URL student_status.json contains Student instance variables C, D, and E.
I need to do the following:
Retrieve the dictionary of students from student_info.json to populate a collection of Students and instantiate them with attributes A and B.
Save this Student collection so that it is accessible throughout the rest of the app's lifecycle.
Retrieve the dictionary of student information from student_status.json and populate Student instance variables C, D, and E for each student in the collection.
From time to time, update the collection of students (in case any were dropped or added).
From time to time, update variables C, D, and E for each student in the collection.
Here are some example files:
File:
student_info.json
Content:
{
"last_updated": 1535936693,
"tyl": 10,
"data": {
"students": [
{
"student_id": "1",
"name": "John Appleseed",
},
{
"student_id": "2",
"name": "Jane Doe"
}
]
}
}
File:
student_status.json
Content:
{
"last_updated": 1535936693,
"tyl": 10,
"data": {
"students": [
{
"student_id": "1",
"number_of_classes": "10",
"GPA": "2.87",
"tuition_due": "237.33"
},
{
"student_id": "2",
"number_of_classes": "10",
"GPA": "2.87",
"tuition_due": "237.33"
}
]
}
}
File
Student.swift
Content
class Student {
var student_id: Int
var name: String
var numberOfClasses: Int?
var gpa: Double?
var tuitionDue: Double?
}
I currently have a nested JSON object which resembles
{
"People": [
{
"Name": "James",
"Age": "18",
"Gender": "Male",
"Sports": []
},
{
"Name": "Sarah",
"Age": "19",
"Gender": "Female",
"Sports": [
"Soccer",
"Basketball",
"Football"
]
}
]
}
Being new to Ruby, I aim to filter throught the entire json and return only the json object/objects in which the "Sports" array has content. So in the above scenario I expect to obtain the object below as a final outcome:
{
"Name": "Sarah",
"Age": "19",
"Gender": "Female",
"Sports": [
"Soccer",
"Basketball",
"Football"
]
}
Will I have to initiate a new method to perform such an act? Or would using regular ruby calls work in this case?
Although #philipyoo answer is right, it miss an explanation on how to "filter" the parsed JSON. If you are new to ruby, take a look at Array#keep_if : http://ruby-doc.org/core-2.2.0/Array.html#method-i-keep_if
require 'json'
people = JSON.parse("{long JSON data ... }")
people_with_sports = people.fetch('People', []).keep_if do |person|
!person.fetch('Sports', []).empty?
end
If you're getting a JSON object from a request, you want to parse it and then you can traverse the hash and arrays to find the information you need. See http://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html
In your case, something like this:
require 'json'
parsed_json = JSON.parse('{"People": [ ... ]}')
parsed_json["People"].each do |person|
puts person if person["name"] == "Sarah"
end
I have the following JSON:
{
"votecategory": [
{
"id": "nlvfl2",
"title": "Best Song",
"pollQuestion": {
"id": "nbprqp",
"title": "best-song",
"displayText": "Best Song",
"answer": [
{
"id": "qylaw4",
"title": "Bruno Mars – Locked Out Of Heaven",
"relatedItems": [
{
"Name": "Bruno Mars",
"id": "sljkur",
"Bio": "Bio info here"
},
{} //Sometimes there's an empty object
],
"winner": "true"
},
{
"id": "q05sb3",
"title": "Daft Punk – Get Lucky (ft. Pharrell Williams)",
"displayText": "Daft Punk – Get Lucky (ft. Pharrell Williams)",
"relatedItems": [
{
"Name": "Daft Punk",
"id": "d9sd84",
"Bio": "Bio info here"
}
]
},
...
]
}
},
...
]
}
Which maps to the following entities:
Category (votecategory values)
Nomination (answer values)
Artist (relatiedItems values)
Ive managed to setup object and relationship mappings for votecategory (category) -> answer (nomination), however I'm having a problem mapping nomination to artist.
What I need to do is have a 1:1 core data relationship setup between nomination and artist, and 1:N relationship setup between artists and nomination (one artist can have multiple nominations).
The problem is that "relatedItems" is an array, but in reality only contains 1 usable value, the related artist. This "should" be a 1:1 relationship from a data perspective, however the JSON maps it as a 1:N relationship, this confuses restkit (rightfully so).
How can I store the single item in the JSON relatedItems response as a single 1:1 relationship?
Thanks
Oli
You could look at using a custom value transformer on that mapping which converts the array into a single object. Check out this question for some additional details.
I have two json objects as below:
obj1= [ { "id": 4, "userId": "abc", "firstName": "abc", "lastName": "abc", "email": "abc#abc.it", "prefers" : [{"breakfast" : "bread" , "lunch" : "non-veg"}] } ]
obj2= [ { "id": 5, "userId": "def", "firstName": "def", "lastName": "def", "email": "def#def.it", "prefers" : [{"breakfast" : "egg" , "lunch" : "veg"}] } ]
Given these to objects i have to validate object2 has the same keys as in object1
diff(obj1,obj2) should give me missing keys
use keys to return an array of keys of the hash and then subtract them
obj1[0].keys - obj2[0].keys
# => array of missing keys
This Ruby JSON comparator will show you how to do it. It is designed to compare the two objects and return true if they're same, but from that you can devise a more complicated return value based on your needs.
If you only want true/false validation that the keys of both objects match, you can do:
object1.keys && object2.keys == object1.keys
That will give you a validation of matching or not.
The default way to output JSON in rails is some thing like:
Code:
render :json => friends.to_json(:only => [:username, :avatar_file_name, :id ])
Output
{"friends" :
[{"user":
{"avatar_file_name": "image1.jpg", "username": "user1", "id": 1}},
{"user":
{"avatar_file_name": "image2.jpg", "username": "user2", "id": 2}},
{"user":
{"avatar_file_name": "image3.jpg", "username": "user3", "id": 3}}
]}
But i want something like:
{"friends" :
{"user": [
{"avatar_file_name": "image1.jpg", "username": "user1", "id": 1},
{"avatar_file_name": "image2.jpg", "username": "user2", "id": 2},
{"avatar_file_name": "image3.jpg", "username": "user3", "id": 3}
]}
}
The class is specified by the array name.
Last.fm also uses this syntax see Last.fm 'API-user.getfriends'
The solution to this problem is commenting the line
ActiveRecord::Base.include_root_in_json = true
in initializers/new_rails_defaults.rb
Or setting ActiveRecord::Base.include_root_in_json to false.
You can use javascript to reformat it:
var json =
{
"friends" :
{ "user": [] }
}
var i = 0;
for ( x in friends )
{
json.friends.user[i].avatar_file_name = x.user.avatar_file_name; // add more fields.
i++;
}
Something among those lines.
JSON is normally used to represent objects in a text format.
So if you like the secon output you must change your objects.
The first output says:
there is a friends object which is a array of user, each user has some properties among which you chose to expose username, avatar_file_name, id
The second output says:
there is a friends object which contains a user object which is an array of unnamed objects, each unnamed objects has some properties...
This second output is not writable in JSON syntax.
It might be:
{"friends" :
{"user": [
["avatar_file_name", "username", "id"],
["image1.jpg", "user1", 1],
["image2.jpg", "user2", 2],
["image3.jpg", "user3", 3]
]}
}
This says:
there is a friends object which contains a user object which is an array of array (a table with field names on first row) ...