yangxu998 / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

Joiner: wrapper for elements #624

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I bumped into a need to wrap my elements with quotes. I think that a 
Joiner.wrap() method which will wrap each element.toString() in the 
collection/iterator/array would be a good addition.

For example:
Suppose we have String[] arr={"element 1","element 2","element 3"};

* Joiner.on(',').wrap('\'').join(arr) -> "'element 1','element 2','element 3'"
* Joiner.on(',').wrap('(',')').join(arr) -> "(element 1),(element 2),(element 
3)"

etc.

Original issue reported on code.google.com by yonatan.graber on 17 May 2011 at 2:50

GoogleCodeExporter commented 9 years ago
This could be handled with a transform, a la:

    @Test
    public void testJoinerWrap() {
        ImmutableList<String> arr = ImmutableList.of("element 1", "element 2", "element 3");

        assertEquals("\"element 1\",\"element 2\",\"element 3\"", wrappedJoin(arr, ","));

    }

    private String wrappedJoin(Iterable<String> arr, String string) {
        Iterable<String> wrappedStrings = Iterables.transform(arr, new Function<String, String>() {
            public String apply(String arg0) {
                return "\"" + arg0 + "\"";
            }}); 
        return Joiner.on(",").join(wrappedStrings);
    }

Original comment by raymond....@gmail.com on 17 May 2011 at 3:44

GoogleCodeExporter commented 9 years ago
Indeed, but it is far less elegant than Joiner.on().wrap().join();

Also, it would handle null differently, since the wrapped string is no
longer a null when using transform. The following test cases would be even
less elegant to achieve using transform (because the null handling would
have to be implemented into the Function object, instead using the
skipNulls() and useForNull() methods):

@Test
public void testJoinerWrapWithSkipNulls() {
  ImmutableList<String> arr = ImmutableList.of("element 1", "element 2",
null,"element 3");
  String output=Joiner.on(',').skipNulls().wrap("\"").join();
  assertEquals("\"element 1\",\"element 2\",\"element 3\"", output);
}

@Test
public void testJoinerWrapWithCustomNulls() {
  ImmutableList<String> arr = ImmutableList.of("element 1", "element 2",
null,"element 3");
  String output=Joiner.on(',').useForNull("NIL").wrap("\"").join();
  assertEquals("\"element 1\",\"element 2\",\"NIL\",\"element 3\"", output);
}

Original comment by yonatan.graber on 17 May 2011 at 3:56

GoogleCodeExporter commented 9 years ago
This is a duplicate with issue 463.

Original comment by amer...@gmail.com on 17 May 2011 at 4:30

GoogleCodeExporter commented 9 years ago
The sensible feature for Joiner to have would be wrapping component strings 
only when they contain a delimiter:

Joiner.on(',').escaped('"').join("a", "b", "c") ---> a,b,c
Joiner.on(',').escaped('"').join("a", "b,c", "d") ---> a,"b,c",d

but the devil's certainly in the details.

Original comment by kevin...@gmail.com on 18 May 2011 at 3:13

GoogleCodeExporter commented 9 years ago
@Kevin, that is a good idea - especially since the wrapper (aka decorator)
idea was rejected in issue 463.
+1 for the delimiter escaping idea.

Original comment by yonatan.graber on 18 May 2011 at 6:11

GoogleCodeExporter commented 9 years ago

Original comment by kevinb@google.com on 13 Jul 2011 at 7:22

GoogleCodeExporter commented 9 years ago
The idea of wrapping with quotes reminded me of this comment by Eric Raymond 
from The Art of UNIX Programming:

"In fact, the Microsoft version of CSV is a textbook example of how not to 
design a textual file format. Its problems begin with the case in which the 
separator character (in this case, a comma) is found inside a field. The Unix 
way would be to simply escape the separator with a backslash, and have a double 
escape represent a literal backslash. This design gives us a single special 
case (the escape character) to check for when parsing the file, and only a 
single action when the escape is found (treat the following character as a 
literal). The latter conveniently not only handles the separator character, but 
gives us a way to handle the escape character and newlines for free. CSV, on 
the other hand, encloses the entire field in double quotes if it contains the 
separator. If the field contains double quotes, it must also be enclosed in 
double quotes, and the individual double quotes in the field must themselves be 
repeated twice to indicate that they don't end the field.

The bad results of proliferating special cases are twofold. First, the 
complexity of the parser (and its vulnerability to bugs) is increased. Second, 
because the format rules are complex and underspecified, different 
implementations diverge in their handling of edge cases. Sometimes continuation 
lines are supported, by starting the last field of the line with an 
unterminated double quote — but only in some products! Microsoft has 
incompatible versions of CSV files between its own applications, and in some 
cases between different versions of the same application (Excel being the 
obvious example here)."

See http://www.faqs.org/docs/artu/ch05s02.html#id2901882

Original comment by nasal...@gmail.com on 16 Apr 2013 at 11:14

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:15

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:09