HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Simplify finding indices of all instances of certain characters in a string

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
indicesinstancesallsimplifyfindingcharacterscertainstring

Problem

I have a string util method for finding potential "wrapping points" in a string.

For example, if " " and "-" are considered wrapping chars, then for input string

"Antoni Gil-Bao" the method would return the sorted set [6, 10].

private static final String WRAPPING_CHARS = " -";
private static final CharMatcher WRAP_CHAR_MATCHER = CharMatcher.anyOf(WRAPPING_CHARS);

public static SortedSet findWrappingIndices(String s) {
    SortedSet indices = Sets.newTreeSet();
    while (WRAP_CHAR_MATCHER.indexIn(s) != -1) {
        int index = WRAP_CHAR_MATCHER.indexIn(s);
        int indexInOriginalString = indices.isEmpty() ? index :  index + indices.last() + 1;
        indices.add(indexInOriginalString);    
        s = s.substring(index + 1);
    }
    return indices;
}


Question is, is there a simpler way to implement this method using Guava? (Besides trivialities like inlining indexInOriginalString.) Based on my unit tests, the above does the job, but it doesn't feel that elegant. Obviously pure Java solutions are welcome too, if they are simpler than my Guava version. In any case, the method should take a String and return SortedSet.

(Background: the reason I just want the indices, instead of doing any string wrapping here directly, is that eventually I'll be operating inside onDraw(), on a char array, and I want to measure pieces of text in the actual font before making wrapping decisions.)

Solution

Simplify is a relative term. If you want simple, then I would have:

public static int[] findWrappingIndices(final String s) {
    int pos = 0;
    int[] ret = new int[s.length()];
    for (int i = 0; i = 0) {
            ret[pos++] = i;
        }
    }
    return Arrays.copyOf(ret, pos);
}


But, you want to complexify it by using a SortedSet (because int[] is not easy to use?), so you can then convert the int[] to the SortedSet.

I don't see why the SortedSet is a good idea, but, it is easy enough to convert to using it (even though it is bigger and slower than an int[] array).

I don't think you will find a simpler (or faster) alternative.

I would guess that you could quavify it with (note the data is being inserted in sorted order anyway):

public static SortedSet findWrappingIndices(final String s) {
    SortedSet indices = Sets.newTreeSet();
    for (int i = 0; i = 0) {
            indices.add(i);
        }
    }
    return indices;
}

Code Snippets

public static int[] findWrappingIndices(final String s) {
    int pos = 0;
    int[] ret = new int[s.length()];
    for (int i = 0; i < s.length(); i++) {
        if (WRAPPING_CHARS.indexOf(s.charAt(i)) >= 0) {
            ret[pos++] = i;
        }
    }
    return Arrays.copyOf(ret, pos);
}
public static SortedSet<Integer> findWrappingIndices(final String s) {
    SortedSet<Integer> indices = Sets.newTreeSet();
    for (int i = 0; i < s.length(); i++) {
        if (WRAPPING_CHARS.indexOf(s.charAt(i)) >= 0) {
            indices.add(i);
        }
    }
    return indices;
}

Context

StackExchange Code Review Q#38477, answer score: 4

Revisions (0)

No revisions yet.