Java JSONArray - comparing elements with other elements within the same JSONArray - java

Am comparing javascript array of elements with other elements within the same array. If elements are same means, I have to give the same number for all the common elements. If the elements are different I have to give some different number for all the nonidentical elements in another element.
for example :
Array structure = [{Location, Date, Number}]
array = [{ 'LA','2017-12-01',1},
{ 'LA','2017-12-01',1},
{ 'NY','2017-12-01',2},
{ 'NY','2016-10-01',3},
{ 'LA','2017-12-01',1},
{ 'LA','2017-12-01',1},
{ 'LA','2017-12-01',1}]
In this array 'Number' is dynamic element, It should be populate on the following rules.
`key1 = location + '-' +date;`
Consider Key1 is the first element ( combination of location + date ). If the same key1 is present in the array, then 'Number' is common for all the same Key1.
In the above example {'LA','2017-12-01',1 } having the same number 1.
{ 'NY','2017-12-01',2} having the number 2. and { 'NY','2016-10-01',3}, having the number 3 because eventhough location is common but date is different.
Please find my code below that am trying. But it giving same number for all the array elements.
JSONObject orderObj=database.getOrder(salesorderId);
JSONArray lineArr = orderObj.getJSONArray("order_items"); //lines
JSONObject lineObj = null;
for(int i=0;i<lineArr.length();i++)
{
lineObj = lineArr.getJSONObject(i);
String source_location=lineObj.getString("source_location");
String key=source_location.concat(lineObj.has("ship_date") ?
lineObj.getString("ship_date") : lineObj.getString("req_ship_date"));
Map map=new HashMap();
if(!map.containsKey(key)){
map.put(key, map.size()+1);
}
lineObj.put("number", map.get(key).toString());
}
orderObj.append("order_items", lineObj);

Move the instantiating of map out of the for loop:
JSONObject orderObj = database.getOrder(salesorderId);
JSONArray lineArr = orderObj.getJSONArray("order_items"); //lines
JSONObject lineObj = null;
// To here:
Map map = new HashMap();
for ( int i = 0; i < lineArr.length(); ++i )
{
lineObj = lineArr.getJSONObject(i);
String source_location = lineObj.getString("source_location");
String key = source_location.concat( lineObj.has("ship_date") ?
lineObj.getString("ship_date") : lineObj.getString("req_ship_date"));
// From here: Map map=new HashMap();
if ( !map.containsKey(key) )
{
map.put(key, map.size() + 1);
}
lineObj.put("number", map.get(key).toString());
}
orderObj.append("order_items", lineObj);

Related

How to count json object item?

I'm parsing a JSON string in Android which looks like this:
[
{
"id":70,
"selection":"25"
},
{
"id":71,
"selection":"50"
},
{
"id":72,
"selection":"50"
}
]
Now I want to get the total count of all selection and display it inside a textview. Can anyone give me an example how to do this, or any tutorial about this?
For example:
selection 25 = 1
selection 50 = 2
Thanks for any help!
I think what you're looking for is something like this:
JsonArray selections = new JsonArray(); // This is your parsed json object
HashMap<Integer, Integer> count = new HashMap<>();
for (JsonElement element : selections) {
JsonObject jsonObject = element.getAsJsonObject();
if(jsonObject.has("selection")) {
int selValue = jsonObject.get("selection").getAsInt();
if(count.containsKey(selValue)) {
count.put(selValue, count.get(selValue) + 1);
} else {
count.put(selValue, 1);
}
}
}
What this will do is loop over your json array and get the value of each selection element. To keep track of the count it increments the count inside of the count hashmap.
You can then get the count for a specific value from the hashmap:
count.get(25); // returns 1
count.get(50); // returns 2
// etc...
If you are using Jackson in Java 8, you can first convert the given JSON string to List<Map<String, Object>>, then transform it into List<Integer> for selection. Finally, you can count occurrences in this list as follows:
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> jsonObj = mapper.readValue(jsonStr, new TypeReference<List<Map<String, Object>>>(){});
Map<Integer, Long> counted = jsonObj.stream()
.map(x -> Integer.valueOf(x.get("selection").toString()))
.collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
System.out.println(counted.toString());
Console output:
{50=2, 25=1}
ArrayList<String> data = new ArrayList<>();
ArrayList<String> datacount = new ArrayList<>();
jsonStr = "Your JSON"
JSONArray jsonArr= null;
try {
jsonArr = new JSONArray(jsonStr);
for (int i = 0; i < jsonArr.length(); i++) {
JSONObject jsonObj = jsonArr.getJSONObject(i);
//here you can set to TextView
String selection = jsonObj.getString("selection");
//System.out.println("adcac"+selection);
if (data.contains(selection)) {
int index = data.indexOf(selection);
int count = Integer.parseInt(datacount.get(index))+1;
// System.out.println("Index==="+index+"---count---"+count);
datacount.set(index,String.valueOf(count));
} else {
datacount.add(String.valueOf(1));
data.add(selection);
}
// Here you can get data and data count...
// System.out.println("data---"+datacount.toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
you can get the array of the json and iterate and calculate the sum of the selection
JSONArray selections = jsonObj.getJSONArray("selections");
// looping through All Selections
int totalCount = selections.length();
Why doesn't anybody use Json Path to solve this in two lines?

JSONObject from dot seperated strings

I am struggling with a specific problem, that I cannot think of correctly. The following is the problem
I have a map with key value like the following, i just used strings here
String key = "activate.message.success"
String value = "success"
String key1 = "activate.title"
String value1 = "Good Title"
String key2 = "activate.message.error"
String value2 = "error"
String key3 = "activate.message.short.poll"
String value3 = "This is short poll"
I need to build a json like the following
{
"activate":{
"message":{
"success":"success",
"error":"error",
"short":{
"poll":"This is short poll"
}
},
"title":"Good Title"
}
}
I could not think of a proper solution for this use case and struggling for 3 hours. I thought of using recursion, but i dont how exactly i could do. Please help with this. I am using java for this, I should use generic JSONObject to solve as there is not POJO mappings. So far I have just splitted the strings using separtor and stored in an another map like the following
public Map<String, Object> getJsonObjectFromKeyValueMap(Map<String, String> stringValueMap,
Map<String, Object> stringObjectMap) {
for (Entry entry : stringValueMap.entrySet()) {
String[] keyValueArrayString = entry.getKey().toString().split("\\.");
int sizeOfMap = keyValueArrayString.length;
int i = 0;
String concatString = "";
for (String processKey : keyValueArrayString) {
if (i < sizeOfMap - 1) {
concatString += processKey + ".";
stringObjectMap.put(concatString, (Object) new JSONObject());
} else {
concatString += processKey;
stringObjectMap.put(concatString, entry.getValue());
concatString = "";
}
i++;
}
}
return stringObjectMap;
}
First, let's update your data into a proper map :
Map<String, String> data = new HashMap<>();
data.put("activate.message.success", "success");
data.put("activate.title", "Good Title");
data.put("activate.message.error", "error");
data.put("activate.message.short.poll", "This is short poll");
Then, your logic is pretty close, for each node but the last, you create a new JSONObject, for the last, you insert the value.
If you try to build a JSONObject instead of the map directly, you would get a pretty good result already, well somewhat of a result.
The following will iterate a Map<String, String> of data.
For each entry, we split the key to getting the nodes.
Then, we just need to move in the json, if a node doesn't exist, we create it.
Then, for the last value, create the value.
public static JSONObject build(Map<String, String> data) {
JSONObject json = new JSONObject();
//Iterate the map entries
for (Entry<String, String> e : data.entrySet()) {
String[] keys = e.getKey().split("\\.");
// start from the root
JSONObject current = json;
for (int i = 0; i < keys.length; ++i) {
String key = keys[i];
//Search for the current node
try {
//If it exist, do nothing
current = current.getJSONObject(key);
} //If it does not exist
catch (JSONException ex) {
//Is it the last node, create the value
if (i == keys.length - 1) {
current.put(key, e.getValue());
} //Not the last node, create a new JSONObject
else {
JSONObject tmp = new JSONObject();
current.put(key, tmp);
current = tmp; //Always replace current with the last node to go deeped each iteration
}
}
}
}
return json;
}
And the example :
public static void main(String[] args) {
Map<String, String> data = new HashMap<>();
data.put("activate.message.success", "success");
data.put("activate.title", "Good Title");
data.put("activate.message.error", "error");
data.put("activate.message.short.poll", "This is short poll");
JSONObject json = build(data);
System.out.println(json.toString(4));
}
Ouptut:
{"activate": {
"message": {
"success": "success",
"short": {"poll": "This is short poll"},
"error": "error"
},
"title": "Good Title"
}}
Note : I used an exception to check for the existance of the key, if the map is huge, this could have some impact so you can simply use :
if(current.isNull(key)){
if (i == keys.length - 1) {
current.put(key, e.getValue());
} else {
JSONObject tmp = new JSONObject();
current.put(key, tmp);
current = tmp;
}
} else {
current = current.getJSONObject(key);
}
This was created using org.json/json

How to return the more than two map objects in Java

Actually I am trying to parse the two api's json data in the same class. I know it should not be done but this is the requirement.
I am getting data from the hashmap. And I want to add it in the table.But the problem is program adds only last item in table. but while debugging it's giving all values.
Here is my code:
public class services2
{
public Map<Object, Object> getReportees(String idOfEmp) throws Exception {
......
if(resp.getStatus() != 200){
System.err.println("Unable to connect to the server");
}
String output = resp.getEntity(String.class);
//Store the JSON objects in an array
//Get the index of the JSON object and print the values as per the index
JSONParser parse = new JSONParser();
JSONObject jobj = (JSONObject)parse.parse(output);
JSONArray jsonarr_1 = (JSONArray) jobj.get("list");
Map<Object, Object> map=new HashMap<Object,Object>();
for(int i=0;i<jsonarr_1.size();i++){
JSONObject jsonobj_1 = (JSONObject)jsonarr_1.get(i);
JSONObject jive = (JSONObject)jsonobj_1.get("jive");
String var = jive.get("username").toString();
values = var;
if(resp1.getStatus() != 200){
system.err.println("Unable to connect to the server");
}
String output1 = resp1.getEntity(String.class);
JSONObject jobjs = (JSONObject) new JSONParser().parse(output1);
JSONArray jsonarr_11 = (JSONArray) jobjs.get("issues");
System.out.println("count"+jsonarr_11.size());
Object obj3 = jsonarr_11.size();
int counter = (Integer) obj3;
System.out.println(counter);
Object obj1 = jsonobj_1.get("displayName");
Object obj2 = jive.get("username");
map.put(obj1, obj2);
map.put("obj3", obj3);
System.out.println(obj3);
}
return map; //for the map obj3 return only the last count that is 1
}
}
Here when I am trying to send the map obj3. I am getting only the last value. I actually want the count in a correct way.
This is the output:
Number id username count
1 A12345 Anagha R 1
2 M12345 Madhusudan S 1
3 AT12345 Amreen Taj 1
Expected output is:
1 A12345 Anagha R 0
2 M12345 Madhusudan S 0
3 AT12345 Amreen Taj 1
When I am trying to print in the console it is giving me the right count but when I am trying through the map it is sending only the last value that is count 1.
You can try using a list of a map like the following:
List<HashMap<Object,Object>>
The problem is in below line of code:
map.put("obj3", obj3);
Each time you are replacing the value for "Obj3" instead of incrementing the existing value of the map.
Instead what you need to do is:
if(map.containsKey("obj3")
{
Object obj3 = map.get("obj3");
//put your logic of incrementing or adding the count
//Lets say it is new Value
map.put("obj3",newValue)
}

get value by key jsonarray

JSONArray arr =
[
{"key1":"value1"},
{"key2":"value2"},
{"key3":"value3"},
{"key4":"value4"}
]
arr.get("key1") throws error. How can I get the value by key in JSONArray?
arr.getString("key1") also throws error. Should I loop through the array? Is it the only way to do it?
What is the error?
In Eclipse Debug perspective, these expressions returns as; error(s)_during_the_evaluation
You can parse your jsonResponse like below code :
private void parseJsonData(String jsonResponse){
try
{
JSONArray jsonArray = new JSONArray(jsonResponse);
for(int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
String value1 = jsonObject1.optString("key1");
String value2 = jsonObject1.optString("key2");
String value3 = jsonObject1.optString("key3");
String value4 = jsonObject1.optString("key4");
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
Sounds like you want to find a specific key from an array of JSONObjects. Problem is, it's an array, so you have to iterate over each element. One solution, assuming no repeat keys is...
private Object getKey(JSONArray array, String key)
{
Object value = null;
for (int i = 0; i < array.length(); i++)
{
JSONObject item = array.getJSONObject(i);
if (item.keySet().contains(key))
{
value = item.get(key);
break;
}
}
return value;
}
Now, let's say you want to find the value of "key1" in the array. You can get the value using the line: String value = (String) getKey(array, "key1"). We cast to a string because we know "key1" refers to a string object.
for (int i = 0; i < arr.length(); ++i) {
JSONObject jsn = arr.getJSONObject(i);
String keyVal = jsn.getString("key1");
}
You need to iterate through the array to get each JSONObject. Once you have the object of json you can get values by using keys
You can easy get a JSON array element by key like this:
var value = ArrName['key_1']; //<- ArrName is the name of your array
console.log(value);
Alternatively you can do this too:
var value = ArrName.key_1;
That's it!

How to parse JSON block in java

I have some piece of JSON information.
Example:
"Items":[{"User":{"Id":"123","name":"abcdef","email":"xy#z.com"},"User":{"Id":"456","name":"def","email":"we#z.com"}}]
I want to remove symbols such as '{','"' and '}' and store it in the ArrayList such that each element in the JSON has a separate position in a new ArrayList.
The output i am expecting looks somewhat like this:
ArrayList[0][0]:Id
ArrayList[0][1]:123
ArrayList[1][0]:name
ArrayList[1][1]:abcdef
etc.,
Sample code:
public String[] ParseGetJSON (String str){
String text = str;
try{
JSONParser jsonParser = new JSONParser();
JSONObject jsonObj = (JSONObject) jsonParser.parse(text);
JSONArray item = (JSONArray) jsonObj.get("Items");
for(int i = 0;i<item.size();i++){
System.out.println("The "+i+" element of the array"+item.get(i));
}
The Output:
The 0 element of the array: {"Id":"123","name":"abcdef","email":"xy#z.com"}
The problem you are having is that your original input JSON is nested more deeply than you are parsing. The output you are seeing when you call item.get(i) makes it clear that each element of item is also a JSONObject, each of which has three fields (Id, name, email).
What you want to do is treat each element as the JSONObject it is, and parse it as well:
for(int i = 0;i<item.size();i++) {
// get the next element as a Object and print it
System.out.println("The "+i+" element of the array: "+item.get(i));
// get the next element as a JSONObject
JSONObject obj = item.getJSONObject(i);
Iterator<String> itr = obj.keys();
// print all its keys/value pairs
while (itr.hasNext()) {
String key = itr.next();
String value = obj.getString(key);
System.out.println("key=" + key + ", value=" + value);
// key=email, value=xy#z.com
// key=name, value=abcdef
// key=Id, value=123
// ...
}
}
Once you have extracted each key and value, you can do whatever you want with them.

Categories

Resources