1

i've got an array of dates as keys and values (integers) in the form:

[2015-07-14] => 40
[2015-07-15] => 5
[2015-07-16] => 8
[2015-07-17] => 0
[2015-07-18] => 0
[2015-07-19] => 0
[2015-07-20] => 0
[2015-07-21] => 0
[2015-07-22] => 0
[2015-07-23] => 0
[2015-07-24] => 0
[2015-07-25] => 0
[2015-07-26] => 0
[2015-07-27] => 0
[2015-07-28] => 0
[2015-07-29] => 0
[2015-07-30] => 0
[2015-07-31] => 0
[2015-08-01] => 0
[2015-08-02] => 1
[2015-08-03] => 1
[2015-08-04] => 2
[2015-08-05] => 1

The startdate and enddate can be selected by the user.

Is there a quick and easy way to combine those dates and sum the values as per month? In my example, the result should look somethine like:

[2015-07] => 53
[2015-08] => 5

The way that I tried to solve that was to use explode functions and then try to recombine those, but that seems to me a bit more complicated than it needs to be.

Stéphane GRILLON
  • 11,140
  • 10
  • 85
  • 154
  • 2
    This seems like a good time to use Java streams and `Collectors.groupingBy`. – Jon Skeet Sep 09 '15 at 13:39
  • How do you create an array of keys and values? Please show us the declaration (and initialization) of that array. – Manu Sep 09 '15 at 13:39

6 Answers6

6

You can use groupingBy with YearMonth as your classifier:

Map<LocalDate, Integer> dateValues = // ...
Map<YearMonth, Integer> res = 
    dateValues.entrySet()
              .stream()
              .collect(groupingBy(e -> YearMonth.from(e.getKey()),
                           summingInt(e -> e.getValue())));
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
3

As long as dates are unique, Using a HashMap<String, Integer> should work.

public static void main(String[] args) {
    Map<String, Integer> dates = new HashMap<String, Integer>();
    dates.put("2015-07-14", 40);
    dates.put("2015-07-15", 8);
    dates.put("2015-07-16", 0);
    dates.put("2015-07-17", 0);
    dates.put("2015-07-18", 0);
    dates.put("2015-08-01", 1);
    dates.put("2015-08-02", 1);
    dates.put("2015-08-03", 2);
    dates.put("2015-08-04", 1);

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

    for (Entry<String, Integer> entry  : dates.entrySet()) {
        String key = entry.getKey().split("-")[0] + "/" + entry.getKey().split("-")[1];
        Integer value = entry.getValue();
        Integer oldValue = result.get(key) != null ? result.get(key) : 0;
        result.put(key, oldValue + value);
    }

    for (Entry<String, Integer> entry  : result.entrySet()) {
        System.out.println("Month " + entry.getKey() + "- Value = " + entry.getValue());
    }

}

OUTPUT (for my example data)

Month 2015/08- Value = 5
Month 2015/07- Value = 48
Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
0

You can add the values like this:

int[][] newarray = new int[latestyear][12];
for(int i = intitialyear; i<finalyear; i++) {
    for(int j = 0; j<12; j++) { //no of months
        int temp = 0;
        for(int k = 0; k<numberofdaysintheparticularmonth; k++) {
            temp = temp + yourcurrentarray[i][j][k];
        }
        newarray[i][j] = temp;
    }
}
burglarhobbit
  • 1,860
  • 2
  • 17
  • 32
0

Use a map . Instantiate to a new Map and then loop through your collection above. Format each date in yyy-MM format . This will be your Map key. If the key does not exist you add it. Then you add it s value to the Map item. This should do it. Not a one liner but it will do

chrisl08
  • 1,658
  • 1
  • 15
  • 24
0

You can use Java 8 map reduce operations; specifically Collectors.groupingBy alongwith Collectors.mapping. https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html

wittyameta
  • 375
  • 1
  • 3
  • 16
0
        Map<String,Integer> myMap = new HashMap<>();
        myMap.put("2015-07-14", 50);
        myMap.put("2015-07-15", 6);
        myMap.put("2015-08-14", 2);
        Map<String,Integer> result = new HashMap<>();
        for (Map.Entry<String, Integer> entry : myMap.entrySet())
        {
            String date = entry.getKey().substring(0, entry.getKey().length()-3);
            if(result.containsKey(date)){
                int value = result.get(date);
                value += entry.getValue();
                result.put(date, value);
            }
            else{
                result.put(date, entry.getValue());
            }
        }
       for (Map.Entry<String, Integer> entry : result.entrySet())
        {
            System.out.println(entry.getKey() + "   " + entry.getValue());
        }
karim mohsen
  • 2,164
  • 1
  • 15
  • 19