diff --git a/src/main/java/strman/Strman.java b/src/main/java/strman/Strman.java index dff10a4..0ccb337 100644 --- a/src/main/java/strman/Strman.java +++ b/src/main/java/strman/Strman.java @@ -33,6 +33,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; +import static java.lang.Math.min; +import static java.util.Collections.emptyList; import static java.util.function.Function.identity; import static java.util.stream.Collectors.*; @@ -1334,5 +1336,57 @@ public abstract class Strman { return countSubstr(value.substring(offset), subStr, allowOverlapping, ++count); } + /** + * Aggregates the contents of n strings into a single list of tuples. + * + * @param inputs A list of strings. + * @return A list of strings if none of the strings in the input is null or empty. + * An empty list otherwise. + */ + public static List zip(String... inputs) { + if (inputs.length == 1) { + return inputs[0].codePoints() + .mapToObj(Character::toChars) + .map(String::new) + .collect(toList()); + } + + int minLength = calculateMinLength(inputs); + + if (minLength == -1) { + return emptyList(); + } + + List zipped = new ArrayList<>(minLength); + + for (int elementIndex = 0; elementIndex < minLength; ++elementIndex) { + StringBuilder tuple = new StringBuilder(); + + for (int inputIndex = 0; inputIndex < inputs.length; ++inputIndex) { + tuple.append(inputs[inputIndex].charAt(elementIndex)); + } + + zipped.add(tuple.toString()); + } + + return zipped; + } + + private static int calculateMinLength(String[] inputs) { + if (inputs.length == 0) { + return -1; + } + + int minLength = Integer.MAX_VALUE; + + for (String input : inputs) { + if (isNullOrEmpty(input)) { + return -1; + } + minLength = min(minLength, input.length()); + } + + return minLength; + } } diff --git a/src/test/java/strman/StrmanTest.java b/src/test/java/strman/StrmanTest.java index 3ca9e18..8082b19 100644 --- a/src/test/java/strman/StrmanTest.java +++ b/src/test/java/strman/StrmanTest.java @@ -26,15 +26,19 @@ package strman; +import org.hamcrest.collection.IsCollectionWithSize; +import org.hamcrest.collection.IsEmptyCollection; import org.junit.Ignore; import org.junit.Test; import java.util.*; +import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining; import static org.hamcrest.collection.IsArrayWithSize.emptyArray; +import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.junit.Assert.*; import static strman.Strman.*; import static strman.Strman.endsWith; @@ -1064,4 +1068,54 @@ public class StrmanTest { assertThat(underscored("FooBarBaz"), equalTo("foo_bar_baz")); assertThat(underscored(" foo bar baz "), equalTo("foo_bar_baz")); } + + @Test + public void zip_shouldReturnEmptyList_whenNullOrEmptyIsPassedIn() { + assertThat(zip("a", null), is(empty())); + assertThat(zip("", "a"), is(empty())); + } + + @Test + public void zip_shouldReturnListOfOneElement_forSimplestValidInput() { + assertThat(zip("a", "b"), equalTo(asList("ab"))); + } + + @Test + public void zip_shouldReturnExpectedListOfPairs_whenBothInputsHaveSameSize() { + assertThat(zip("abc", "def"), equalTo(asList("ad", "be", "cf"))); + assertThat(zip("ABC", "DEF"), equalTo(asList("AD", "BE", "CF"))); + } + + @Test + public void zip_shouldReturnExpectedListOfPairs_whenFirstInputIsBiggerThanSecond() { + assertThat(zip("abc", "d"), equalTo(asList("ad"))); + assertThat(zip("ABCDE", "FGH"), equalTo(asList("AF", "BG", "CH"))); + } + + @Test + public void zip_shouldReturnExpectedListOfPairs_whenSecondInputIsBiggerThanFirst() { + assertThat(zip("d", "abc"), equalTo(asList("da"))); + assertThat(zip("FGH", "ABCDE"), equalTo(asList("FA", "GB", "HC"))); + } + + @Test + public void zip_shouldReturnExpectedListOfTriplets_whenThreeInputs() { + assertThat(zip("abc", "def", "ghi"), equalTo(asList("adg", "beh", "cfi"))); + } + + @Test + public void zip_shouldReturnExpectedListOfTuples_whenMoreThanThreeInputs() { + assertThat(zip("abc", "def", "ghi", "123"), equalTo(asList("adg1", "beh2", "cfi3"))); + } + + @Test + public void zip_shouldReturnEmptyList_whenNotEnoughInputs() { + assertThat(zip(), is(empty())); + } + + @Test + public void zip_shouldReturnInputInListForm_whenOnlyOneInput() { + assertThat(zip("zip"), is(equalTo(asList("z", "i", "p")))); + assertThat(zip("z"), is(equalTo(asList("z")))); + } }