Reputation: 33
Assuming my delimiter is ',' (comma), I'm looking for a function split
that will guarantee that the returned String[] array is a certain size (no more, no less):
String[] split(String str, int limit);
split("hello", 2); => ["hello", ""]
split("hello,", 2); => ["hello", ""]
split(",hello", 2); => ["", "hello"]
split("hello,world", 2); => ["hello", "world"]
split("hello,world,goodbye", 2); => ["hello", "world,goodbye"]
See how the array size is always 2? I can get some of this behavior with Pattern.split, but not for every case... How can I do this?
Upvotes: 3
Views: 3001
Reputation: 181
Simply getting the position of the delimiter and using substrings gets you there pretty easily:
public static String[] split(String str, int limit){
String[] arr = new String[limit];
for(int i = 0; i < limit-1; i++){
int position = str.indexOf(',');
int length = str.length();
if(position == -1){
arr[i]= str.substring(0,length);
str = str.substring(length, length);
}
else{
arr[i] = str.substring(0, position);
str = str.substring(position+1, length);
}
}
arr[limit-1] = str;
return arr;
}
Upvotes: 0
Reputation: 10852
It seems that it would be easy enough to pad out a new array with empty strings. Here is a utility method you could use to perform this split.
public static String[] split(Pattern pattern, CharSequence input, int limit) {
// perform the split
tokens = pattern.split(input, limit);
int tokenCount = tokens.length();
if (tokenCount == limit) {
// if no padding is necessary, return the result of pattern.split
return tokens;
} else {
// create a new array, copy tokens into array, pad with empty string
String[] padded = Arrays.copyOf(tokens, limit);
for (int i = tokenCount; i < limit; i++) {
padded[i] = "";
}
return padded;
}
}
Edit: Updated to shamelessly steal [Arrays.copyOf
][1] from unholysampler's answer.
[1]: http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#copyOf(T[], int)
Upvotes: 0
Reputation: 17321
You can use Arrays.copyOf()
to return a padded array. However, the padding will be null
instead of an empty string.
String[] parts = Arrays.copyOf("hello,".split(",", 2), 2);
String[] parts1 = Arrays.copyOf(",hello".split(",", 2), 2);
String[] parts2 = Arrays.copyOf("hello,world".split(",", 2), 2);
String[] parts3 = Arrays.copyOf("hello,world,goodbye".split(",", 2), 2);
String[] parts4 = Arrays.copyOf("hello,".split(",", 2), 4); //null padding
Upvotes: 3
Reputation: 3731
You could do it with a loop that scans the string searching for the delimiter, then put whatever is not ahead of the delimiter in the array, then re-do it until it hits the top array size, that way it just return whatever was ahead as the last entry in the array:
public string[] mySplit(String Split, char Delimiter, int Top)
{
string[] returned = new string[Top];
for(int i = 0; i < Top; i++){
if(i==Top)
{
returned[i] = Split; return;
}
else
{
int compPlace = 0;
char comp = Split.toCharArray()[compPlace];
while(comp != Delimiter)
{
compPlace++;
comp = Split.toCharArray()[compPlace];
}
returned[i] = Split.SubString(0,compPlace);
Split = Split.SubString(compPlace);
}
}
return returned;
}
Im sure youll have to tweak this as i have a little headache as of now :)
Upvotes: 0
Reputation: 1371
Well, if I understood you correctly you just want to stop splitting as soon as you have a reached the count provided via argument and move the remaining bit wholly into the last field, right? In addition, the limit-parameter should always ensure the fieldcount?
Wrap a method around the Pattern.split() method which just adds fields until your limit/threshold/minimum is reached.
for(i=0;i<limit;++i){
//add empty fields to array until limit is reached
}
Upvotes: 0
Reputation: 597116
StringUtils.split(string, separator, max)
is very close to what you need.
Then you can use ArrayUtils.addAll(result, emptyArray)
, where emptyArray
is an array of size max - result.length
.
The functionality you want is too specific, so I doubt there will be anything ready-to-use.
Upvotes: 1
Reputation: 216
I don’t remember all the syntax by heart, but your are looking at something like this:
Pattern p = new Pattern("[^,]+");
String[] strings = new String[limit];
int offset = 0;
int i = 0;
for (; i < limit; i++) {
Match m = str.match(p, offset);
if (m == null) break;
offset += m.string.length + 1;
strings[i] = m.string;
}
for (; i < limit; i++) {
strings[i] = "";
}
Again, this is not valid Java
Upvotes: 0