Read JSON questions file - JAVA game - arrays

I have the following JSON file with questions and answer options.
And the code I used trying to print the questions.
{
"GameName": "millionaire game",
"level": 1,
"questions": [
{
"question1": "What is the minimum of players in a footbal game?",
"options1": [
8,
10,
9,
7
],
"answer1": "7"
},
{
"question2": "Who scored maximum goal footbal game?",
"options2": [
"Jhon",
"Pitty",
"Richard",
"Mike"
],
"answer2": "Mike"
},
{
"question3": "What is the maximum of players in a footbal game?",
"options3": [
8,
10,
9,
7
],
"answer3": "7"
}
]
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Random;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.json.*;
public class readJson {
public static void main(String[] args) throws JSONException {
String first = "jsonPerguntas2.json";
try {
String content = new String((Files.readAllBytes(Paths.get(first))));
JSONObject o = new JSONObject(content);
JSONArray firstQuestion = o.getJSONArray("question1");
//System.out.println(conteudo);
for (int i=0; i<firstQuestion.length(); i++){
System.out.println(firstQuestion.get(i));
}
} catch (IOException e) {
}
}
}
I have this code to read the file. But it always return the same error:
Exception in thread "main" org.json.JSONException: JSONObject["question1"] not found.
at org.json.JSONObject.get(JSONObject.java:454)
at org.json.JSONObject.getJSONArray(JSONObject.java:535)
at TrabPraticoJava.TesteLerJson.main(TesteLerJson.java:37)
C:\Users\José Dias\Documents\NetBeansProjects\TrabPraticoJava\nbproject\build-impl.xml:1341: The following error occurred while executing this line:
C:\Users\José Dias\Documents\NetBeansProjects\TrabPraticoJava\nbproject\build-impl.xml:936: Java returned: 1
BUILD FAILED (total time: 0 seconds)
If I change the line JSONArray firstQuestion = o.getJSONArray("question1"); to JSONArray firstQuestion = o.getJSONArray("questions"); it actually prints the all file but I want to print the questions separately.
Can someone help me out?
Thanks in advance

Try this:
JSONArray questions = o.getJSONArray("questions");
for (int i = 0; i < questions.length(); i++) {
JSONObject question = recs.getJSONObject(i);
System.out.println(question.getInt("question"+i+1));
}

Related

display content-type(Strategy) fields value in the form of array in groovy

I have a snippets of groovy code (inside strategy.groovy file) as shown below in which I want to display the output in the form of desired array.
The content-type Strategy (in crafter) has the following fields:
Title English (title_en_t)
Title French (title_fr_t)
Description English (description_en_t)
Description French (description_fr_t)
Players (players_o)
groovy code (inside strategy.groovy file):
private createStrategyElement(rootStrategy, ctx) {
Element strategy = new DefaultElement("strategy")
strategy.addElement("players_o.first_name_s").text = rootStrategy.players_o.item.component.first_name_s != null ? rootStrategy.players_o.item.component.first_name_s : "" //Line A
strategy.addElement("players_o.last_name_s").text = rootStrategy.players_o.item.component.last_name_s != null ? rootStrategy.players_o.item.component.last_name_s : "" //Line B
return strategy
}
Line A and Line B display the o/p in the following fashion:
current o/p:
players_o.first_name_s: "[John, The]"
players_o.last_name_s: "[Cena, Undertaker]"
PROBLEM STATEMENT:
I am wondering what changes I need to do in the groovy code above at Line A and Line B so that it displays the o/p in this fashion:
DESIRED O/P:
players: [{
"item": [
{
"first_name_s": "John",
"last_name_s": "Cena"
},
{
"first_name_s": "The",
"last_name_s": "Undertaker"
}
]
}]
don't know what is the crafter-cms. and you have not provided the input for your code.
i found DefaultElement and addElement in dom4j library - so i assume it's the one used in crafter-cms
https://dom4j.github.io/javadoc/2.0.1/org/dom4j/tree/DefaultElement.html
you are expecting json in output but dom4j used to work with xml...
however. just a try
private createStrategyElement(rootStrategy, ctx) {
Element strategy = new DefaultElement("strategy")
def players = strategy.addElement('players')
for(i in rootStrategy.players_o.item.component){
def item = players.addElement('item')
item.addElement('first_name_s').text = i.first_name_s
item.addElement('last_name_s').text = i.last_name_s
}
return strategy
}
the following code i used to debug it in standard groovy console:
#Grab(group='org.dom4j', module='dom4j', version='2.1.3')
import org.dom4j.tree.DefaultElement
import org.dom4j.Element
import org.dom4j.io.XMLWriter
import org.dom4j.io.OutputFormat
def rootStrategy=[
players_o:[
item:[
component:[
[
first_name_s:'John',
last_name_s: 'Cena',
],
[
first_name_s:'The',
last_name_s: 'Undertaker'
],
]
]
]
]
private createStrategyElement(rootStrategy, ctx) {
Element strategy = new DefaultElement("strategy")
def players = strategy.addElement('players')
for(i in rootStrategy.players_o.item.component){
def item = players.addElement('item')
item.addElement('first_name_s').text = i.first_name_s
item.addElement('last_name_s').text = i.last_name_s
}
return strategy
}
println new StringWriter().with{w->
new XMLWriter(w, OutputFormat.createPrettyPrint()).write( createStrategyElement(rootStrategy,null) )
w.toString()
}

adding up the value of an array with another array

can I get the sum of amount if I have an array like the one below?
[{"_id":"5e154cf38c52231ee19f8",
"refunds":[
{"_id":"5e38f10a754fcf3d48015",
"reason":"refund 1",
"amount":50000,
]},
{"_id":"5e1578b48c52231ee19f8",
"refunds":[
{"_id":"5e37e09ef9ea5e3784043",
"reason":"refund 1",
"amount":100000,
{"_id":"5e37e12a02c27c14580a1",
"reason":"refund 2",
"amount":100000,
{"_id":"5e38f02b754fcf3d48015",
"reason":"refund 3",
"amount":50000,
]},
{"_id":"5e1578b48c52231ee19f8",
"refunds":[]
}]
I hope to get res = 300000
This should be relatively straightforward, we create a flat array of all refund objects using flatMap, then we'll use reduce to sum the total amount.
I've added another function, sumRefundAmountsII to workaround JavaScript environments that do not support.flatMap (pre ES2019)
const data = [ { "_id": "5e154cf38c52231ee19f8", "refunds": [ { "_id": "5e38f10a754fcf3d48015", "reason": "refund 1", "amount": 50000 } ] }, { "_id": "5e1578b48c52231ee19f8", "refunds": [ { "_id": "5e37e09ef9ea5e3784043", "reason": "refund 1", "amount": 100000 }, { "_id": "5e37e12a02c27c14580a1", "reason": "refund 2", "amount": 100000 }, { "_id": "5e38f02b754fcf3d48015", "reason": "refund 3", "amount": 50000 } ] }, { "_id": "5e1578b48c52231ee19f8", "refunds": [] }];
function sumRefundAmounts(array) {
// Get an array of all refunds.
const refunds = array.flatMap(obj => obj.refunds);
// Sum amount for each refund.
return refunds.reduce((sum, refund) => {
return sum + refund.amount;
}, 0);
}
console.log("Total amount:", sumRefundAmounts(data));
// Use this function if your JavaScript environment complains about .flatMap
function sumRefundAmountsII(array) {
// Use a work around if we don't have flatMap...
const refunds = [].concat.apply([], array.map(obj => obj.refunds));
// Sum amount for each refund.
return refunds.reduce((sum, refund) => {
return sum + refund.amount;
}, 0);
}
console.log("Total amount (no flat map):", sumRefundAmountsII(data));
Before answering ... I assume 2 things -
1st - you are looking answer in the Java. 2nd - And you can do things much easier way in java List :
Let we make 2 classes Refund & Composite (Containing List)-
Refund Class -
package com.sabre.ticketing.dhs.service.create.domain;
public class Refund {
String _id;
String reason;
int amount;
public Refund(String _id, String reason, int amount) {
this._id = _id;
this.reason = reason;
this.amount = amount;
}
public int getAmount() {
return amount;
}
}
And here is Composite Class as -
package com.sabre.ticketing.dhs.service.create.domain;
import java.util.List;
public class Composite {
String _id;
List<Refund> refunds;
public Composite(String _id, List<Refund> refunds) {
this._id = _id;
this.refunds = refunds;
}
public List<Refund> getRefunds() {
return refunds;
}
}
The calculation technique is in SumCalc class -
package com.sabre.ticketing.dhs.service.create.domain;
import java.util.ArrayList;
import java.util.List;
public class SumCalc {
public static void main(String[] args){
List<Composite> composites = List.of(new Composite("5e154cf38c52231ee19f8", List.of(new Refund("5e38f10a754fcf3d48015", "refund 1", 50000))),
new Composite("5e154cf38c52231ee19f8",
List.of(new Refund("5e37e09ef9ea5e3784043", "refund 1", 100000),
new Refund("5e37e12a02c27c14580a1", "refund 2", 100000),
new Refund("5e38f02b754fcf3d48015", "refund 3", 50000))),
new Composite("5e154cf38c52231ee19f8", new ArrayList<>()));
// Basically get you Json converted into composites list.. for simplicity and dont want to jackson thing i have initialized list as new ..
Integer finalSum = composites.stream()
.map(Composite::getRefunds)
.flatMap(List::stream)
.map(Refund::getAmount)
.reduce((sum, val) -> sum + val)
.orElse(0);
System.out.println("final Sum is " + finalSum);
}
}
Run the SumClac ...
final Sum is 300000
Process finished with exit code 0

Reading data from Firebase

I'm working on an ionic app, which I would like to integrate with firebase. I have the following code in my home.ts file:
export class HomePage {
UHSGetMonths$: Observable < any[] > ;
constructor(public navCtrl: NavController,
public platform: Platform,
private screenOrientation: ScreenOrientation,
private UHSMonths: UHSGetMonthsService,
public actionSheetCtrl: ActionSheetController,
private localNotifications: LocalNotifications,
public alertCtrl: AlertController) {
this.platform.ready().then((ready) => {
this.localNotifications.on('tap', (notification, state) => {
let json = JSON.parse(notification.data);
let alert = this.alertCtrl.create({
title: notification.title,
subTitle: json.fullMsq
});
alert.present();
});
});
//this.screenOrientation.lock(this.screenOrientation.ORIENTATIONS.PORTRAIT);
this.UHSGetMonths$ = this.UHSMonths
.getUHSMonthsList() // DB LIST
.snapshotChanges() // Give access to both Key and Value
.map(changes => {
return changes.map(c => ({
key: c.payload.key,
...c.payload.val(),
}));
});
}
}
I can successfully retrieve the data in my template files but how do get access a value in firebase database from the home.ts? In Firebase, I have meeting names and times for each month. E.g. for July, the team briefing takes place at 10am. How can I get the value 10am to use and manipulate in my home.ts?
Thanks
Firebase JSON file snippet:
[ {
"days" : [ {
"StaffBriefing" : "10:00",
"Team A Meeting" : "11:30",
"Team B Meeting" : "13:00",
"Team C Meeting" : "15:30",
"Date" : "01"
}, {
"StaffBriefing" : "14:00",
"Team A Meeting" : "12:45",
"Team B Meeting" : "14:00",
"Team C Meeting" : "16:30",
"Date" : "02"
}, {
"StaffBriefing" : "09:00",
"Team A Meeting" : "14:00",
"Team B Meeting" : "11:00",
"Team C Meeting" : "15:30",
"Date" : "03"
} ],
"monthName" : "January"
} ]
Update - 03/08/2018
Yes, I added the subscription code after the this.UHSGetMonths$. However, the following code worked:
`this.JubileeMonths
.getJubileeMonthsList() // DB LIST
.valueChanges()
.subscribe(data => {
console.log(data);
});`
And the console.log(data) displays:
If I do console.log(data[0]); I get this, which is fine.
However, If I try doing console.log(data[0].monthName); I get an error in my code editor (Atom) i.e. **Property 'monthName' does not exist on type '{}'` but in the console I get the correct value of January.
Why the error in the code editor or am I doing this all wrong?
Thanks.
UHSGetMonthsService
import { Injectable } from '#angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import * as moment from 'moment';
#Injectable()
export class UHSGetMonthsService {
private UHSGetMonthsRef$ = this.fbDB.list('UHS/Calendar/months');
constructor(private fbDB: AngularFireDatabase) {
}
getUHSMonthsList() {
return this.UHSGetMonthsRef$;
}
}
Given your database structure, you could do this after UHSGetMonths$ is set:
this.UHSGetMonths$
.subscribe(months => {
if (months && months.length) {
let month = months.find(m => m.monthName === 'January');
let day = month.days.find(d => d.Date === '02');
console.log(day['Team C Meeting']);
}
});
If you wanted to get the current month's name for the .find(), you'd need to either use this post's solution or momentjs.
If you wanted to get the current day of the month, you can use new Date().getDate() or momentjs again.
Update:
You're getting the error because you haven't defined the "shape" of the return data, so as far as your IDE knows, it's just a generic object. To fix this, create an interface that matches what the data looks like and use it on your list reference.
import { Injectable } from '#angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import * as moment from 'moment';
export interface Month {
monthName: string;
days: any[];
}
#Injectable()
export class UHSGetMonthsService {
private UHSGetMonthsRef = this.fbDB.list<Month>('UHS/Calendar/months');
constructor(private fbDB: AngularFireDatabase) {
}
getUHSMonthsList() {
return this.UHSGetMonthsRef;
}
}

Parsing SolrJ Facet Pivot Response

I have a Solr Schema and I am trying to do Facet Pivoting on it by passing multiple fields in facet.pivot parameter while making a call through SolrJ. My Solr response looks something like below:
"facet_pivot": {
"boolean_value,int_value": [
{
"field": "boolean_value",
"value": false,
"count": 1,
"pivot": [
{
"field": "int_value",
"value": 364,
"count": 1
}
]
},
{
"field": "boolean_value",
"value": true,
"count": 2,
"pivot": [
{
"field": "int_value",
"value": 406,
"count": 1
},
{
"field": "int_value",
"value": 409,
"count": 1
}
]
}
]
}
How, can I parse the above response using SolrJ in form of Nested objects i.e. PivotField having relation of which int_value falls under which boolean_value.
SolrJ Version tried: 4.10.4
Update:
When you make a call through SolrJ check the SolrQuery that gets generated. In my above case the SolrQuery was:
facet.pivot=boolean_value&facet.pivot=int_value
Solr considers above pivots as two different ones and you won't get nested pivoting. For Nested Pivoting your SolrQuery should have
facet.pivot=boolean_value,int_value
I had the same problem and wrote a simple tester application. It queries Solr and writes the pivot values to StdOut as hierarchical Strings. If there are any suggestions to implement that more nicely, please let me know. Here's the code:
public class Tester {
public static final String HIERARCHICAL_FACET_SEPARATOR = "/";
public static void main(String[] args) throws SolrServerException, IOException {
CloudSolrClient solr = ... ;
SolrQuery query = new SolrQuery(...);
query.setFacet(true);
query.addFacetPivotField(new String[]{"field1,field2,field3"});
QueryResponse result = solr.query(query);
NamedList<List<PivotField>> facetPivot = result.getFacetPivot();
List<String> parsedPivotResult = parsePivotResult(facetPivot);
parsedPivotResult.forEach((s) -> {
System.out.println(s);
});
}
private static List<String> parsePivotResult(final NamedList<List<PivotField>> pivotEntryList) {
final Set<String> outputItems = new HashSet<>();
for (final Entry<String, List<PivotField>> pivotEntry : pivotEntryList) {
System.out.println("Key: " + pivotEntry.getKey());
pivotEntry.getValue().forEach((pivotField) -> {
renderOutput(new StringBuilder(), pivotField, outputItems);
});
}
final List<String> output = new ArrayList<>(outputItems);
Collections.sort(output);
return output;
}
private static void renderOutput(final StringBuilder sb, final PivotField field, final Set<String> outputItems) {
final String fieldValue = field.getValue() != null ? ((String) field.getValue()).trim() : null;
final StringBuilder outputBuilder = new StringBuilder(sb);
if (field.getPivot() != null) {
if (outputBuilder.length() > 0) {
outputBuilder.append(HIERARCHICAL_FACET_SEPARATOR);
}
outputBuilder.append(fieldValue);
outputItems.add(new StringBuilder(outputBuilder).append(" (").append(field.getCount()).append(")").toString());
field.getPivot().forEach((subField) -> {
renderOutput(outputBuilder, subField, outputItems);
});
} else {
if (outputBuilder.length() > 0) {
outputBuilder.append(HIERARCHICAL_FACET_SEPARATOR);
}
outputBuilder.append(fieldValue);
outputItems.add(outputBuilder.append(" (").append(field.getCount()).append(")").toString());
}
}
}

How to convert array of ints to string?

I need convert array of ints to string. Following code doing it, but in result I am getting unwanted symbols [ ]
import std.stdio;
import std.conv;
void main()
{
int [] x = [1,3,4,6];
string s = to!string(x);
writeln(s);
}
output: [1, 3, 4, 6]
How I can remove brackets without hack with replace?
You can do it for example like this:
import std.stdio;
import std.conv;
import std.algorithm;
void main()
{
int [] x = [1,3,4,6];
writeln(x.map!(to!string).joiner(", "));
}
You can use std.format
import std.format;
import std.stdio;
void main()
{
auto res = format("%(%s, %)", [1,2,3,4,5]);
writeln(res); // output: 1, 2, 3, 4, 5
}

Resources