Given a numeric string, I would like to apply an operation every nth digit in the string. Is this possible with java streams?
For example, for the string "12345" and applying a sum of 3 on every 2nd character, the result would be "15375".
public static void main(String[] args) {
"12345".chars()
.mapToObj(Character::getNumericValue)
.mapToInt(c -> c 3) //should only happen every 2nd character
.forEach(System.out::print);
}
The above results in 45678 because the sum is applied to all characters.
CodePudding user response:
I believe this is what you are looking for:
public static void main(String[] args) {
String string = "12345";
String result = IntStream.range(0, string.length())
.mapToObj(index -> incrementCharAtEvenIndex(string, index, 3))
.collect(Collectors.joining());
System.out.println(result);
}
static String incrementCharAtEvenIndex(String string, int index, int increment) {
int number = Character.getNumericValue(string.charAt(index));
if ((index 1) % 2 == 0) {
number = number increment;
}
return String.valueOf(number);
}
Unfortunately, Stream API is not built to work with the indices directly, so you have to use IntStream to simulate for-loop and a custom method to increment a numeric character if it appears at the even index (remember it starts at 0).
CodePudding user response:
You can use the range operator to add a index to your stream:
String myString = "12345";
int n = 2;
IntStream
.range(0, myString.length())
.mapToObj(i -> Map.entry(i, Character.getNumericValue(myString.charAt(i))))
.mapToInt(pair -> (pair.getKey() 1) % n == 0 ? pair.getValue() 3 : pair.getValue())
.forEach(System.out::print);
CodePudding user response:
You can do it like this.
String s = "12345";
String result = update(s, 2, 3);
System.out.println(result);
prints
15375
- takes a string, skip value, and increment
- use
(i 1)%nto start withnthcharacter. - use ternary operator (
?:) to map to the sum depending on the remainder of the index to the skip value. - return new String
public static String update(String str, int n, int inc) {
return IntStream.range(0, str.length())
.mapToObj(i -> String.valueOf((i 1) % n == 0 ?
str.charAt(i) - '0' inc :
str.charAt(i) - '0'))
.collect(Collectors.joining());
}
CodePudding user response:
I actually had a solution using indices but I was not sure if there was a way to avoid that. Apparently not.
This also works:
public static void main(String[] args) {
char[] chars = "12345".toCharArray();
String collect = IntStream.range(0, chars.length)
.map(index -> {
int value = getNumericValue(chars[index]);
return (index % 2 != 0) ? value 3 : value;
})
.mapToObj(String::valueOf)
.collect(Collectors.joining());
System.out.println(collect);
}
