How can I convert a map like
{
"name": "my name",
"date": "14 Feb 2020",
"days": "15",
}
Into something like
[
"my name",
"14 Feb 2020"
"15"
]
Basically converting map values into List.
I've tried
list.add(name) and so on
but there will be problems if there is many data. Is there any way to iterate to get the expected result?
You can get a value list using the values getter.
final map = {
"name": "my name",
"date": "14 Feb 2020",
"days": "15",
};
map.values.toList(); // <---- Here
Map myMap = {"name":"mike", "age":"12};
List myList = myMap.values.toList();
Related
I want groupBy of famousAs of this data.
I got my data from api something like this
Personality:[
0: {
"FullName":"Harry Potter",
"DateOfBirth": "2020/02/16",
"Department":"Branch Operation",
"BirthDay":"Friday"
"famousAs":"Actor"
},
1: {
"FullName":"John Wick",
"DateOfBirth": "2020/02/16",
"Department":"Finance",
"BirthDay":"Friday"
"famousAs":"Actor"
},
2: {
"FullName":"Priyanka Chopara",
"DateOfBirth":2020/02/19,
"Department":"Loan",
"BirthDay":"Monday"
"famousAs":"Actress"
}
]
when i check ,type of this data then it is showing List of dynamic
If your want to group list of data according to their property value.
You can use .where() method to filter out the list.
List filter(List items, String value) =>
items.where((element) => element['famousAs'] == value).toList();
First the api response data from your question is invalid.
If your List is same as following above filter function will work fine.
or if your api response is HashMap change to Map first
[
{
"FullName": "Harry Potter",
"DateOfBirth": "2020/02/16",
"Department": "Branch Operation",
"BirthDay": "Friday",
"famousAs": "Actor"
},
{
"FullName": "John Wick",
"DateOfBirth": "2020/02/16",
"Department": "Finance",
"BirthDay": "Friday",
"famousAs": "Actor"
},
{
"FullName": "Priyanka Chopara",
"DateOfBirth": 2020 / 02 / 19,
"Department": "Loan",
"BirthDay": "Monday",
"famousAs": "Actress"
}
]
Usage..
final actors = filter(items, 'Actor');
final actresses = filter(items, 'Actress');
This is slightly hard to explain for me so I'll do my best. Here is the given data set:
Name
Car Brand
Car Model
Car Color
Year Bought
Tom
Toyota
Corolla
Black
2009
Tom
Hyundai
Kona
Blue
2010
Tom
Kia
Soul
Red
2011
Bob
Mazda
CX-30
Red
2008
Bob
BMW
X1
Blue
2014
With the given data set, I want to condense it based on name and just put all the cars into a list and output it out as JSON objects on separated lines in file. For the above data set, the output should look like this:
{
"name": "Tom",
"Cars": [{
"CarSpecifications": {
"Brand": "Toyota",
"Model": "Corolla",
"Color": "Black"
},
"YearBought":2009
},
{
"CarSpecifications": {
"Brand": "Hyundai",
"Model": "Kona",
"Color": "Blue"
},
"YearBought":2010
},
{
"CarSpecifications": {
"Brand": "Hyundai",
"Model": "Kona",
"Color": "Blue"
},
"YearBought":2011
}]
}
{
"name": "Bob",
"Cars": [{
"CarSpecifications": {
"Brand": "Mazda",
"Model": "CX-30",
"Color": "Red"
},
"YearBought":2008
},
{
"CarSpecifications": {
"Brand": "BMW",
"Model": "X1",
"Color": "Blue"
},
"YearBought":2014
}]
}
How could I accomplish these transformations using Scala and Scala Dataframes?
You can aggregate the dataset using groupBy & collect_list and generate JSON strings with toJSON:
df.groupBy("Name").agg(collect_list(
struct(
struct(
$"Car Brand".as("Brand"),
$"Car Model".as("Model"),
$"Car Color".as("Color")
).as("CarSpecifications"),
$"Year Bought".as("YearBought")
).as("CarSpecifications")
).as("Cars"))
.toJSON
.show(false)
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|value |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|{"Name":"Tom","Cars":[{"CarSpecifications":{"Brand":"Toyota","Model":"Corolla","Color":"Black"},"YearBought":"2009"},{"CarSpecifications":{"Brand":"Hyundai","Model":"Kona","Color":"Blue"},"YearBought":"2010"},{"CarSpecifications":{"Brand":"Kia","Model":"Soul","Color":"Red"},"YearBought":"2011"}]}|
|{"Name":"Bob","Cars":[{"CarSpecifications":{"Brand":"Mazda","Model":"CX-30","Color":"Red"},"YearBought":"2008"},{"CarSpecifications":{"Brand":"BMW","Model":"X1","Color":"Blue"},"YearBought":"2014"}]} |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
I'm trying to add a day to my dates which look like "2020-11-20" for November, 20, 2020. However I am encountering difficulty doing that - do I need to use the offset function? The reason I am doing this is that Vega-Lite is automatically offsetting my dates back 1 day through its GMT conversion and I cannot get it to stop. Please help!
Here is an example. If you look at the timeline graph it ends at 2020-11-19, but the final date in my data is 2020-11-20, and I need to make it so 2020-11-20 is the last date on my timeline graph.
This issue comes from an unfortunate "feature" of how javascript parses dates. Here is a minimal example of the problem you're seeing (open in editor):
{
"data": {
"values": [
{"date": "2020-11-17", "value": 5},
{"date": "2020-11-18", "value": 6},
{"date": "2020-11-19", "value": 7},
{"date": "2020-11-20", "value": 8}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "value", "type": "quantitative"},
"y": {
"field": "date",
"timeUnit": "yearmonthdate",
"type": "ordinal"
},
"tooltip": [
{
"field": "date",
"timeUnit": "yearmonthdate",
"type": "temporal"
}
]
}
}
Each of the days in the chart are off by one compared to the input. So why is this happening?
Well, it turns out that the Vega-Lite's renderer makes use of Javascript's built-in date parsing, and Javascript's date parsing treats inputs differently depending on how they're formatted. In particular, Javascript will parse non-standard timestamps in UTC time, but will parse full ISO-8601 timestamps in local time, a fact you can confirm in your browser's javascript console (I executed this on a computer set to PST):
> new Date('2020-11-20')
Thu Nov 19 2020 16:00:00 GMT-0800 (Pacific Standard Time)
> new Date('2020-11-20T00:00:00')
Fri Nov 20 2020 00:00:00 GMT-0800 (Pacific Standard Time)
The Vega-Lite docs recommend using UTC timeUnits and scales to work around this, but I tend to find that approach a bit clunky. Instead, I try to always specify dates in Vega-Lite via full ISO 8601 timestamps.
In your case, the best approach is probably to use a calculate transform to regularize your dates, and proceed from there. Modifying the simplified example above, it might look something like this (open in editor):
{
"data": {
"values": [
{"date": "2020-11-17", "value": 5},
{"date": "2020-11-18", "value": 6},
{"date": "2020-11-19", "value": 7},
{"date": "2020-11-20", "value": 8}
]
},
"transform": [
{"calculate": "toDate(datum.date + 'T00:00:00')", "as": "date"}
],
"mark": "bar",
"encoding": {
"x": {"field": "value", "type": "quantitative"},
"y": {
"field": "date",
"timeUnit": "yearmonthdate",
"type": "ordinal"
},
"tooltip": [
{
"field": "date",
"timeUnit": "yearmonthdate",
"type": "temporal"
}
]
}
}
I would like to create an array of dates (or of tuples including an index and a data) from the following JSON.
My code is creating an array but instead of creating an array of dates, it breaks up the dates into characters. What do I need to do to create an array just of dates.
JSON looks like:
let json = """
[{"date":"2017-01-05",
"price":119.34},{"date":"2017-01-06",
"price":118.93}];
Code is:
let myprices = try JSONDecoder().decode([Prices].self, from: Data(json.utf8))
let dates = myprices.sorted{$0.date < $1.date}.enumerated().map {Array($0.element.date)}
Code prints to console as:
dates [["2", "0", "1", "7", "-", "0", "1", "-", "0", "5"], ["2", "0", "1", "7", "-", "0", "1", "-", "0", "6"], ["2", "0", "1", "7", "-", "0", "1", "-", "0"]]
Thanks in advance for any suggestions.
Replace
let dates = myprices.sorted{$0.date < $1.date}.enumerated().map {Array($0.element.date)}
with
let dates = myprices.sorted{$0.date < $1.date}.map { $0.date }
Currently you may be making let data:String change it to let date:Date and supply a formatter to the decoder check This
I am using the Wunderground API in my project, and the part of the API I want to use looks like this:
"history": {
"dailysummary": [
{ "date": {
"pretty": "12:00 PM PDT on August 12, 2015",
"year": "2015",
"mon": "08",
"mday": "12",
"hour": "12",
"min": "00",
"tzname": "America/Los_Angeles"
},
"fog":"0","rain":"0","snow":"0","snowfallm":"0.00", "snowfalli":"0.00","monthtodatesnowfallm":"", "monthtodatesnowfalli":"","since1julsnowfallm":"", "since1julsnowfalli":"","snowdepthm":"", "snowdepthi":"","hail":"0","thunder":"0","tornado":"0","meantempm":"26", "meantempi":"79","meandewptm":"16", "meandewpti":"60","meanpressurem":"1014", "meanpressurei":"29.94","meanwindspdm":"9", "meanwindspdi":"5","meanwdire":"","meanwdird":"331","meanvism":"16", "meanvisi":"10","humidity":"","maxtempm":"33", "maxtempi":"91","mintempm":"19", "mintempi":"66","maxhumidity":"78","minhumidity":"34","maxdewptm":"17", "maxdewpti":"62","mindewptm":"15", "mindewpti":"59","maxpressurem":"1016", "maxpressurei":"30.01","minpressurem":"1012", "minpressurei":"29.88","maxwspdm":"24", "maxwspdi":"15","minwspdm":"0", "minwspdi":"0","maxvism":"16", "maxvisi":"10","minvism":"16", "minvisi":"10","gdegreedays":"28","heatingdegreedays":"0","coolingdegreedays":"14","precipm":"0.00", "precipi":"0.00","precipsource":"","heatingdegreedaysnormal":"0","monthtodateheatingdegreedays":"0","monthtodateheatingdegreedaysnormal":"0","since1sepheatingdegreedays":"","since1sepheatingdegreedaysnormal":"","since1julheatingdegreedays":"0","since1julheatingdegreedaysnormal":"17","coolingdegreedaysnormal":"5","monthtodatecoolingdegreedays":"106","monthtodatecoolingdegreedaysnormal":"69","since1sepcoolingdegreedays":"","since1sepcoolingdegreedaysnormal":"","since1jancoolingdegreedays":"600","since1jancoolingdegreedaysnormal":"280" }
]
}
For some reason, dailysummary, which has both "{}" brackets and "[]" brackets, cannot be accessed the way I would normally, like this:
var jsonData = json["history"]["dailysummary"]["fog"]
which, if this worked normally, would return the fog value in my function. The function works fine; I've tested it with other parts of the API. Is there something specific that needs to be done for dailysummary?
You're misinterpreting how to call json. It might help to beautify the json to look like the below:
{
"history": {
"dailysummary": [{
"date": {
"pretty": "12:00 PM PDT on August 12, 2015",
"year": "2015",
"mon": "08",
"mday": "12",
"hour": "12",
"min": "00",
"tzname": "America/Los_Angeles"
},
"fog": "0",
...
}]
}
}
With the above it's pretty self explanatory that dailysummary is an array containing a single object. To access 'fog' you call it via json.history.dailysummary[0].fog