Repository: jtablesaw/tablesaw
Pull request #266 (2018-04-06 13:58:40)

Cleanup
Thanks for contributing.

- [x] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)

## Description

testing for StringMapUtils and some minor code cleanup

## Testing

Did you add a unit test?
yup


Patch:
diff --git a/core/src/main/java/tech/tablesaw/columns/strings/StringMapUtils.java b/core/src/main/java/tech/tablesaw/columns/strings/StringMapUtils.java
index 7031c230..cb70a6e7 100644
--- a/core/src/main/java/tech/tablesaw/columns/strings/StringMapUtils.java
+++ b/core/src/main/java/tech/tablesaw/columns/strings/StringMapUtils.java
@@ -25,8 +25,8 @@ import tech.tablesaw.columns.Column;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * String utility functions. Each function takes one or more String columns as input and produces
@@ -95,7 +95,6 @@ public interface StringMapUtils extends Column {
     default StringColumn substring(int start, int end) {
 
         StringColumn newColumn = StringColumn.create(name() + "[sub]");
-
         for (int r = 0; r < size(); r++) {
             String value = getString(r);
             newColumn.append(value.substring(start, end));
@@ -103,7 +102,10 @@ public interface StringMapUtils extends Column {
         return newColumn;
     }
 
-
+    /**
+     * Returns a column containing the substrings from start to the end of the input
+     * @throws java.lang.StringIndexOutOfBoundsException if any string in the column is shorter than start
+     */
     default StringColumn substring(int start) {
 
         StringColumn newColumn = StringColumn.create(name() + "[sub]");
@@ -115,10 +117,13 @@ public interface StringMapUtils extends Column {
         return newColumn;
     }
 
+    /**
+     * Abbreviates a String using ellipses. This will turn
+     * "Now is the time for all good men" into "Now is the time for..."
+     * @param maxWidth  the maximum width of the resulting strings, including the elipses.
+     */
     default StringColumn abbreviate(int maxWidth) {
-
         StringColumn newColumn = StringColumn.create(name() + "[abbr]");
-
         for (int r = 0; r < size(); r++) {
             String value = getString(r);
             newColumn.append(StringUtils.abbreviate(value, maxWidth));
@@ -126,6 +131,15 @@ public interface StringMapUtils extends Column {
         return newColumn;
     }
 
+    default StringColumn format(String formatString) {
+
+        StringColumn newColumn = StringColumn.create(name() + "[formatted]");
+        for (int r = 0; r < size(); r++) {
+            newColumn.append(String.format(formatString, getString(r)));
+        }
+        return newColumn;
+    }
+
     default StringColumn padEnd(int minLength, char padChar) {
 
         StringColumn newColumn = StringColumn.create(name() + "[pad]");
@@ -175,7 +189,7 @@ public interface StringMapUtils extends Column {
     /**
      * Returns a column containing the levenshtein distance between the two given string columns
      */
-    default Column distance(Column column2) {
+    default NumberColumn distance(Column column2) {
 
         NumberColumn newColumn = NumberColumn.create(name() + column2.name() + "[distance]");
 
@@ -187,26 +201,13 @@ public interface StringMapUtils extends Column {
         return newColumn;
     }
 
-    default StringColumn join(Column column2, String delimiter) {
-
-        StringColumn newColumn = StringColumn.create(name() + column2.name() + "[joining]");
-
-        for (int r = 0; r < size(); r++) {
-            String[] values = new String[2];
-            values[0] = getString(r);
-            values[1] = column2.getString(r);
-            newColumn.append(StringUtils.join(values, delimiter));
-        }
-        return newColumn;
-    }
-
     /**
      * Return a copy of this column with the given string appended
      *
      * @param columns the column to append
      * @return the new column
      */
-    default StringColumn concatenate(String separator, StringColumn ... columns) {
+    default StringColumn join(String separator, StringColumn ... columns) {
         StringColumn newColumn = StringColumn.create(name() + "[column appended]", this.size());
         for (int r = 0; r < size(); r++) {
             String result = getString(r);
@@ -266,7 +267,7 @@ public interface StringMapUtils extends Column {
             List<String> tokens =
                     new ArrayList<>(splitter.splitToList(value));
             Collections.sort(tokens);
-            value = String.join(" ", tokens);
+            value = String.join(separator, tokens);
             newColumn.append(value);
         }
         return newColumn;
@@ -293,19 +294,19 @@ public interface StringMapUtils extends Column {
         return newColumn;
     }
 
-    default StringColumn tokenizeAndRemoveDuplicates() {
+    default StringColumn tokenizeAndRemoveDuplicates(String separator) {
         StringColumn newColumn = StringColumn.create(name() + "[without duplicates]", this.size());
 
         for (int r = 0; r < size(); r++) {
             String value = getString(r);
 
-            Splitter splitter = Splitter.on(CharMatcher.whitespace());
+            Splitter splitter = Splitter.on(separator);
             splitter = splitter.trimResults();
             splitter = splitter.omitEmptyStrings();
             List<String> tokens = new ArrayList<>(splitter.splitToList(value));
 
-            value = String.join(" ", new HashSet<>(tokens));
-            newColumn.append(value);
+            String result = tokens.stream().distinct().collect(Collectors.joining(separator));
+            newColumn.append(result);
         }
         return newColumn;
     }


Test patch:
diff --git a/core/src/test/java/tech/tablesaw/TableFilteringTest.java b/core/src/test/java/tech/tablesaw/TableFilteringTest.java
index 41680faf..572bcb82 100644
--- a/core/src/test/java/tech/tablesaw/TableFilteringTest.java
+++ b/core/src/test/java/tech/tablesaw/TableFilteringTest.java
@@ -49,6 +49,19 @@ public class TableFilteringTest {
         }
     }
 
+    /**
+     * Tests that you can reference a column in a table that is returned by query, without creating a variable for the
+     * intermediate table
+     */
+    @Test
+    public void testQueryChaining() {
+        Table structureWithoutDates =
+                table.structure()
+                    .rejectWhere(stringColumn("column type").equalsIgnoreCase("Local_Date"));
+        assertEquals(2, structureWithoutDates.rowCount());
+        assertFalse(structureWithoutDates.stringColumn("Column Name").contains("Date"));
+    }
+
     @Test
     public void testReject() {
         Table result = table.rejectWhere(numberColumn("approval").isLessThan(70));
diff --git a/core/src/test/java/tech/tablesaw/api/StringColumnTest.java b/core/src/test/java/tech/tablesaw/api/StringColumnTest.java
index ce343358..062e656b 100644
--- a/core/src/test/java/tech/tablesaw/api/StringColumnTest.java
+++ b/core/src/test/java/tech/tablesaw/api/StringColumnTest.java
@@ -254,4 +254,210 @@ public class StringColumnTest {
         List<String> states = stringColumn.asList();
         assertEquals(51, states.size()); //includes Wash. DC
     }
+
+    @Test
+    public void testFormatting() {
+        String[] names = {"John White", "George Victor"};
+        StringColumn nameColumn = StringColumn.create("names", names);
+        StringColumn formatted = nameColumn.format("Name: %s");
+        assertEquals("Name: John White", formatted.get(0));
+    }
+
+    @Test
+    public void testDistance() {
+        String[] words = {"canary", "banana", "island", "reggae"};
+        String[] words2 = {"cancel", "bananas", "islander", "calypso"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn word2Column = StringColumn.create("words2", words2);
+        NumberColumn distance = wordColumn.distance(word2Column);
+        assertEquals(distance.get(0), 3, 0.0001);
+        assertEquals(distance.get(3), 7, 0.0001);
+    }
+
+    @Test
+    public void testCommonSuffix() {
+        String[] words = {"running", "icecube", "regular", "reggae"};
+        String[] words2 = {"rowing", "cube", "premium", "place"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn word2Column = StringColumn.create("words2", words2);
+        StringColumn suffix = wordColumn.commonSuffix(word2Column);
+        assertEquals(suffix.get(0), "ing");
+        assertEquals(suffix.get(1), "cube");
+        assertEquals(suffix.get(3), "e");
+    }
+
+    @Test
+    public void testCommonPrefix() {
+        String[] words = {"running", "icecube", "back"};
+        String[] words2 = {"rowing", "iceland", "backup"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn word2Column = StringColumn.create("words2", words2);
+        StringColumn result = wordColumn.commonPrefix(word2Column);
+        assertEquals(result.get(0), "r");
+        assertEquals(result.get(1), "ice");
+        assertEquals(result.get(2), "back");
+    }
+
+    @Test
+    public void testPadStart() {
+        String[] words = {"running", "icecube", "back"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.padStart(8, ' ');
+        assertEquals(result.get(0), " running");
+        assertEquals(result.get(1), " icecube");
+        assertEquals(result.get(2), "    back");
+    }
+
+    @Test
+    public void testPadEnd() {
+        String[] words = {"running", "icecube", "back"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.padEnd(8, 'X');
+        assertEquals(result.get(0), "runningX");
+        assertEquals(result.get(1), "icecubeX");
+        assertEquals(result.get(2), "backXXXX");
+    }
+
+    @Test
+    public void testSubstring() {
+        String[] words = {"running", "icecube", "back"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.substring(3);
+        assertEquals(result.get(0), "ning");
+        assertEquals(result.get(1), "cube");
+        assertEquals(result.get(2), "k");
+    }
+
+    @Test
+    public void testSubstring2() {
+        String[] words = {"running", "icecube", "back"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.substring(1,3);
+        assertEquals(result.get(0), "un");
+        assertEquals(result.get(1), "ce");
+        assertEquals(result.get(2), "ac");
+    }
+
+    @Test
+    public void testReplaceFirst() {
+        String[] words = {"running", "run run run"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.replaceFirst("run","walk");
+        assertEquals(result.get(0), "walkning");
+        assertEquals(result.get(1), "walk run run");
+    }
+
+    @Test
+    public void testReplaceAll() {
+        String[] words = {"running", "run run run"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.replaceAll("run","walk");
+        assertEquals(result.get(0), "walkning");
+        assertEquals(result.get(1), "walk walk walk");
+    }
+
+    @Test
+    public void testReplaceAll2() {
+        String[] words = {"running", "run run run"};
+        String[] regex = {"n", "g"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.replaceAll(regex,"XX");
+        assertEquals(result.get(0), "ruXXXXiXXXX");
+        assertEquals(result.get(1), "ruXX ruXX ruXX");
+    }
+
+    @Test
+    public void testJoin() {
+        String[] words = {"running", "run"};
+        String[] words2 = {"walking", "walk"};
+        String[] words3 = {"swimming", "swim"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn wordColumn2 = StringColumn.create("words2", words2);
+        StringColumn wordColumn3 = StringColumn.create("words3", words3);
+        StringColumn result = wordColumn.join("--", wordColumn2, wordColumn3);
+        assertEquals(result.get(0), "running--walking--swimming");
+        assertEquals(result.get(1), "run--walk--swim");
+    }
+
+    @Test
+    public void testTrim() {
+        String[] words = {" running ", " run run run "};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.trim();
+        assertEquals(result.get(0), "running");
+        assertEquals(result.get(1), "run run run");
+    }
+
+    @Test
+    public void testUpperCase() {
+        String[] words = {"running", "run run run"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.upperCase();
+        assertEquals(result.get(0), "RUNNING");
+        assertEquals(result.get(1), "RUN RUN RUN");
+    }
+
+    @Test
+    public void testLowerCase() {
+        String[] words = {"RUNNING", "RUN RUN RUN"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.lowerCase();
+        assertEquals(result.get(0), "running");
+        assertEquals(result.get(1), "run run run");
+    }
+
+    @Test
+    public void testAbbreviate() {
+        String[] words = {"running", "Stop Breaking Down", "Backwards Writing"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.abbreviate(10);
+        assertEquals(result.get(0), "running");
+        assertEquals(result.get(1), "Stop Br...");
+        assertEquals(result.get(2), "Backwar...");
+    }
+
+    @Test
+    public void tokenizeAndSort() {
+        String[] words = {"Stop Breaking Down", "Backwards Writing"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.tokenizeAndSort();
+        assertEquals(result.get(0), "Breaking Down Stop");
+        assertEquals(result.get(1), "Backwards Writing");
+    }
+
+    @Test
+    public void tokenizeAndSort1() {
+        String[] words = {"Stop,Breaking,Down", "Writing Backwards"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.tokenizeAndSort(",");
+        assertEquals(result.get(0), "Breaking,Down,Stop");
+        assertEquals(result.get(1), "Writing Backwards");
+    }
+
+    @Test
+    public void tokenizeAndRemoveDuplicates() {
+        String[] words = {"Stop Breaking Stop Down", "walk run run"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.tokenizeAndRemoveDuplicates(" ");
+        assertEquals("Stop Breaking Down", result.get(0));
+        assertEquals("walk run", result.get(1));
+    }
+
+    @Test
+    public void chainMaps() {
+        String[] words = {"Stop Breaking Stop Down", "walk run run"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.tokenizeAndRemoveDuplicates(" ").tokenizeAndSort();
+        assertEquals("Breaking Down Stop", result.get(0));
+        assertEquals("run walk", result.get(1));
+    }
+
+    @Test
+    public void chainMaps1() {
+        String[] words = {"foo", "bar"};
+        StringColumn wordColumn = StringColumn.create("words", words);
+        StringColumn result = wordColumn.concatenate(" bam");
+        assertEquals("foo bam", result.get(0));
+        assertEquals("bar bam", result.get(1));
+    }
 }
\ No newline at end of file