Stéphane GRILLON
Stéphane GRILLON

Reputation: 11872

Combine array of dates and sum values per month in Java

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.

Upvotes: 1

Views: 1819

Answers (6)

Jean Logeart
Jean Logeart

Reputation: 53839

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())));

Upvotes: 6

karim mohsen
karim mohsen

Reputation: 2254

        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());
        }

Upvotes: 0

wittyameta
wittyameta

Reputation: 395

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

Upvotes: 0

Jordi Castilla
Jordi Castilla

Reputation: 26981

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

Upvotes: 3

chrisl08
chrisl08

Reputation: 1658

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

Upvotes: 0

burglarhobbit
burglarhobbit

Reputation: 2291

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;
    }
}

Upvotes: 0

Related Questions