2

I have data in the following format:

["DATA1-1","DATA1-2","DATA1-3","DATA1-4","","DATA2-1","DATA2-2","DATA2-3","DATA2-4","","DATA3-1","DATA3-2","DATA3-3","DATA3-4",""]

I would like to split this array into several arrays, where the delimiter should be an empty item (""). Something like this:

[["DATA1-1","DATA1-2","DATA1-3","DATA1-4"],["DATA2-1","DATA2-2","DATA2-3","DATA2-4"],["DATA3-1","DATA3-2","DATA3-3","DATA3-4"]].  

This is the code I came up with:

private List<List<String>> retrieveData(List<String> arrayIn)
{

    List<List<String>> subArrays = new ArrayList<>();

    List<String> tempArrays = new ArrayList<>();

    for(int i=0; i<arrayIn.size(); i++)
    {
        if(!airwayIn.get(i).equals("") && i != (airwayIn.size()-1) )
        {
            tempArrays.add(airwayIn.get(i));
        }
        else if (airwayIn.get(i).equals("") || i == (airwayIn.size()-1) )
        {
            subArrays.add(tempArrays);
            tempArrays = new ArrayList<>();
        }
    }

    return subArrays;
}

But I was wondering whether there is a more elegant code to do it. For example, this is what I use in Swift:

let subArrays: [[String]] = airwayIn.split(separator: "").map{Array($0)}

Thank you!

Igor Tupitsyn
  • 1,193
  • 3
  • 18
  • 45

2 Answers2

0

Here's a solution using Java 8:

private List<List<String>> retrieveData (List<String> list)
{
    // get all the indexes of the empty strings
    int [] indexes = 
                  Stream.of(IntStream.of(-1), IntStream.range(0, list.size())
                  .filter(i -> list.get(i).equals("")), IntStream.of(list.size()))
                  .flatMapToInt(s -> s).toArray();

    // Split into sub lists based on the indexes
    List<List<String>> subLists = 
              IntStream.range(0, indexes.length - 2)
                     .mapToObj(i -> list.subList(indexes[i] + 1, indexes[i + 1]))
                     .collect(Collectors.toList());

    System.out.println(subLists);
    return subLists;
}

Outputs:

[[DATA1-1, DATA1-2, DATA1-3, DATA1-4], [DATA2-1, DATA2-2, DATA2-3, DATA2-4], [DATA3-1, DATA3-2, DATA3-3, DATA3-4]]
Michael Markidis
  • 4,163
  • 1
  • 14
  • 21
  • I don't think this is more elegant just because it uses Streams. In this case a normal for loop is the best solution IMO – Felix Jul 01 '17 at 04:13
0

You can do it with a simple for loop, e.g.:

String[] array  = {"DATA1-1","DATA1-2","DATA1-3","DATA1-4","","DATA2-1","DATA2-2","DATA2-3","DATA2-4","","DATA3-1","DATA3-2","DATA3-3","DATA3-4",""};
List<List<String>> result = new ArrayList<>();
List<String> elements = new ArrayList<>();
for(String s : array){
    if("".equals(s) && !elements.isEmpty()){
        result.add(elements);
        elements = new ArrayList<>();
    }else{
        elements.add(s);
    }
}
//Add the remaining elements
if(!elements.isEmpty()){
    result.add(elements);
}
System.out.println(result);
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
  • Somebody seems to be downvoting everything and then voting to delete the answers. I don't know why, unless their criteria is that the answer has to be as brief as the Swift answer. – ajb Jul 01 '17 at 04:47
  • 1
    @ajb I would appreciate a comment in case an answer gets downvoted. Downvoting without any comment does not make any sense unless the answer is totally wrong. – Darshan Mehta Jul 01 '17 at 06:56
  • Yeah... unfortunately the SO staff doesn't seem inclined to require one. – ajb Jul 01 '17 at 06:59
  • Totally agreed! – Igor Tupitsyn Jul 01 '17 at 14:33