tags:

views:

44

answers:

1

Hi, Before I begin, this is my JSON: (The structure is rigid, and cant be changed)

[
  {"_id":{"country":"au", "industry":"foo"}, "value":{"count":2}},
  {"_id":{"country":"au", "industry":"bar"}, "value":{"count":1}},
  {"_id":{"country":"be", "industry":"baz"}, "value":{"count":2}},
  ..
]

I cant have duplicate country names, and industry names. I have an array that is to be filled with values as

array[au][foo] = 2

array[au][bar] = 1

array[be][baz] = 2

the values are unsorted in the JSON, and all countries might not have the same industries.

How do i go about doing that? This is my current code:

for (int i = 0; i < jsonArray.size(); i++) {
        JSONObject jsonValue = jsonArray.get(i).isObject();

        JSONObject _id = jsonValue.get("_id").isObject();
        JSONObject value = jsonValue.get("value").isObject();

        String country = _id.get("country").isString().toString();
        setCountry.add(country);

        String industry = _id.get("industry").isString().toString();
        setIndustry.add(industry);

        int count = Integer.parseInt(value.get("count").isNumber()
                .toString());

    }

Im adding the country and industry to a set, to remove the duplicates. thats what causing the issue about the count. I dont care for it to be elegant, a hackjob will also do.

Thanks.

+1  A: 

I think you can make use of enum's for your problem.Define all the known country names and Industry in an enum like this.

public enum Country {
au,
be;
int Int=this.ordinal();//just a short name for ordinal
}

and

public enum Industry {
foo,
bar,
baz;
int Int=this.ordinal();
}

Now define a 2d int array and you can set the value's using the enum's like this :

int[][] value=new int[Country.values().length][Industry.values().length];
value[Country.au.Int][Industry.bar.Int]=2;
//Read from JSON
value[Country.valueOf("au").Int][Industry.valueOf("bar").Int]=2;

You can add this code to the end of your current for loop if your using enum's:

value[Country.valueOf(country).Int][Industry.valueOf(industry).Int]=count;

Another option is to avoid an array and use Map instead:

Map<Country,Map<Industry,Integer>> m=new HashMap<Country,Map<Industry,Integer>>();

or simply without enums :

Map<String,Map<String,Integer>> m=new HashMap<String,Map<String,Integer>>();

The problem with map is that it is a bit tricky to add and retrieve value's from it but you can write common method's to do this job.

UPDATE:

Adding values to inner map:

String[][] countryAndIndustry= {{"au","foo"},{"au","bar"},{"be","baz"}};
Integer[] count= {2,1,2};
HashMap<String,HashMap<String,Integer>> hm=new HashMap<String,    HashMap<String,Integer>>();
for(int i=0;i<count.length;i++)
{
    HashMap<String,Integer> innerMap=hm.get(countryAndIndustry[i][0]);
    if(innerMap==null)
    {
        innerMap=new HashMap<String, Integer>();
        hm.put(countryAndIndustry[i][0],innerMap);
    }
    innerMap.put(countryAndIndustry[i][1],count[i]);
}
Emil
i think ill try the Map method, because I have no idea firsthand which industries there are going to be.
Kaustubh P
I am facing problems with this implementation too, because the country name occurs more than once in the JSON, which promptly over-writes the 2nd Map which is the Key of the outer map.
Kaustubh P
@Kaustubh:I have updated the code.Check it.
Emil
yeah, that did the trick. i had to play around with the indexes a lot, ended up with unclean code.
Kaustubh P