0

I have got an array of objects of the form:

[
    {
        "id": "id_1",
        "type": "A",
        "value": "value_1",
        "label": "label_1"
    },
    {
        "id": "id_2",
        "type": "B",
        "value": "value_2",
        "label": "label_2"
    },
    {
        "id": "id_3",
        "type": "C",
        "value": "value_3",
        "label": "label_3"
    },
    {
        "id": "id_4",
        "type": "A",
        "value": "value_4",
        "label": "label_4"
    }
]

This needs to become an array of arrays. Where The arrays are grouped by type. And the id field can be omitted.

So I should end up with:

[
    [
        {
            "value": "value_1",
            "label": "label_1"
        },
        {
            "value": "value_4",
            "label": "label_4"
        }
    ],
    [
        {
            "value": "value_2",
            "label": "label_2"
        }
    ],
    [
        {
            "value": "value_3",
            "label": "label_3"
        }
    ]
]

I want to avoid using loops if possible. Any help would be greatly appriciated!

6
  • 1
    "I want to avoid using loops if possible" Why? Commented May 27, 2020 at 9:30
  • 1
    So you tried nothing at all but already know that loops should be avoided? In a grouping-and-sorting-scenario? Commented May 27, 2020 at 9:31
  • 1
    simple, you override compareTo and sort the original array. Then you only need to iterate once over the original array (looping, streaming...iterating) and for every element you check if it belongs to the previous sub array or if you need to create a new one. Commented May 27, 2020 at 9:36
  • I have tried using loops, but it got messy really quick. I'm looking for a way on doing this using streams and a method similair to reduse in typescript. Commented May 27, 2020 at 9:36
  • 1
    @GameDroids I'll try that. I'll post update my post it if I was sucessfull. Commented May 27, 2020 at 9:38

1 Answer 1

1

I would try it like this:

Arrays.sort(originalArray, (o1, o2) -> o1.getType().compareTo(o2.getType()));

which would simply result in an "ordered by type". If you wish you can also sort the "sub arrays" like this:

Arrays.sort(originalArray, (o1, o2) -> {
     int compare = o1.getType().compareTo(o2.getType());
     if(compare == 0){
         return o1.getValue().compareTo(o2.getValue());
     }else{
         return compare;
     }
});

which will sort by value if the types of two elements are equal. Now it is much much simpler if you where to use Lists to process the elements and if needed you can convert the lists back to arrays.

ArrayList<ArrayList> result = new ArrayList<ArrayList>(); // this is going to be your result list (untyped in this example)
ArrayList newList = new ArrayList();  // first you create the very first sub list
newList.add(originalList.get(0));     // add the first element to the first sublist
result.add(newList); // then you add the first list to your result list 

int i=0;             // this is going to be the index for the "result list"

for(MyObject element : originalList){
    // you check if the next element is part of the last list you added 
    if(result.get(i).get(result.get(i).size()-1).getType()==element.getType()){   // if the last element of your last list is of the same type as the current element you are checking
        result.get(i).add(element);    // then you just add the element to the last list
    }else{
        ArrayList newList = new ArrayList();  // otherwise you create a new list
        newList.add(element);                 // add the element to it
        result.add(newList);                  // and you add the new list to your result list
        i++;  // since you have now a new sub list you increment the index
    }
}

Sorry if it looks messy - there are still a lot of things to enhance, I just thought it would help you to see one possible implementation (with one simple loop)

Sign up to request clarification or add additional context in comments.

2 Comments

I had to make some minor changes, but your solution works fine. I had to make the following changes: 1. skip the first element in the for loop, because it is already added to the result. 2. Cast to MyObject type in the if statement. 3. Rename the second newList variable , because it is already defined in scope. Thank you for your help!
Oh right, my first idea was an indexed loop that starts at 1, of course now the first element would be added twice. Sorry. I also skipped any checks (if the element is really present, if it has a type etc..) I am happy that I was of help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.