Separator idiom

Discussion in 'Java' started by Roedy Green, Jun 13, 2008.

  1. Roedy Green

    Roedy Green Guest

    Lets say you want to create a list of items separated by something
    e.g. comma <BR> \n etc, but you don't want a terminator.

    How do you go about constructing it with minimal fuss?
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jun 13, 2008
    #1
    1. Advertising

  2. Roedy Green <> wrote:
    > Lets say you want to create a list of items separated by something
    > e.g. comma <BR> \n etc, but you don't want a terminator.
    > How do you go about constructing it with minimal fuss?


    Iterator<String> it=list.iterator();
    while (it.hasNext()) {
    System.out.print(it.next());
    if (it.hasNext()) System.out.print(sepChar);
    }

    Less fuss in Tcl: puts [join $list $sepChar]
     
    Andreas Leitgeb, Jun 13, 2008
    #2
    1. Advertising

  3. Roedy Green

    Guest

    On 13 ÉÀÎ, 16:20, Roedy Green <>
    wrote:
    > How do you go about constructing it with minimal fuss?


    public static String build(List<?> list, String separator) {
    StringBuilder buf = new StringBuilder();
    for (Object obj : list) {
    if (buf.length() > 0) {
    buf.append(separator);
    }
    buf.append(obj);
    }
    return buf.toString();
    }


    BR,
    Alex
     
    , Jun 13, 2008
    #3
  4. Roedy Green

    Stefan Ram Guest

    Roedy Green <> writes:
    >Lets say you want to create a list of items separated by something
    >e.g. comma <BR> \n etc, but you don't want a terminator.
    >How do you go about constructing it with minimal fuss?


    Because I do not know the meaning of »fuss«,
    I will ignore » with minimal fuss«:

    public static java.lang.CharSequence format
    ( final java.lang.CharSequence[] source )
    { final java.lang.StringBuilder text = new java.lang.StringBuilder();
    boolean first = true;
    for( final java.lang.CharSequence component : source )
    { if( first )first = false; else text.append( "\n" );
    text.append( component ); }
    return text; }
     
    Stefan Ram, Jun 13, 2008
    #4
  5. Roedy Green

    Stefan Ram Guest

    Eric Sosman <> writes:
    > // Treat first item as "special"
    > System.out.print(array[0]);
    > for (int i = 1; i < array.length; ++i) {
    > System.out.print(", ");
    > System.out.print(array);
    > }
    >[...] I actively try to avoid the first.


    What I like about it, is that it avoids the run-time overhead
    to check the position within the loop.

    Two problems with this are: It can not be generalized to loops
    with for( ... : ... ), and it needs an additional »if« to be correct:

    // Treat first item as "special"
    if (array.length > 0) {
    System.out.print(array[0]);
    for (int i = 1; i < array.length; ++i) {
    System.out.print(", ");
    System.out.print(array);
    }
    }
     
    Stefan Ram, Jun 13, 2008
    #5
  6. Roedy Green

    Mark Space Guest

    Stefan Ram wrote:

    >
    > What I like about it, is that it avoids the run-time overhead
    > to check the position within the loop.
    >


    It seems like one should be able to generate the sequence as normal,
    then shorten the output to remove the last separator. This should be
    very efficient, as reducing the size of a buffer or file is almost cost
    free.


    public String sequence( Object [] obj, String sep ) {

    StringBuilder sb = new StringBuilder();
    for( Object o : obj ) {
    sb.append( o );
    sb.append( sep );
    }
    if( sb.length() >= sep.length() ) {
    sb.setLength( sb.length() - sep.length() )
    }
    return sb.toString();
    }

    But I'm not seeing a way to make that complete general (I can't find a
    way to trim the size of both a StringWriter and a FileWriter. I need
    some sort of random access for both. Or at least a way to change the
    file length.)
     
    Mark Space, Jun 14, 2008
    #6
  7. Roedy Green

    Daniel Pitts Guest

    wrote:
    > On 13 ÉÀÎ, 16:20, Roedy Green <>
    > wrote:
    >> How do you go about constructing it with minimal fuss?

    >
    > public static String build(List<?> list, String separator) {
    > StringBuilder buf = new StringBuilder();
    > for (Object obj : list) {
    > if (buf.length() > 0) {
    > buf.append(separator);
    > }
    > buf.append(obj);
    > }
    > return buf.toString();
    > }
    >
    >
    > BR,
    > Alex

    get apache commons, and use StringUtils.join().

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, Jun 14, 2008
    #7
  8. Roedy Green

    Daniel Pitts Guest

    Roedy Green wrote:
    > Lets say you want to create a list of items separated by something
    > e.g. comma <BR> \n etc, but you don't want a terminator.
    >
    > How do you go about constructing it with minimal fuss?

    In JSP, I use the varStatus.last or first property.
    In Java, if I can't use apache-commons-lang StringUtils, I tend to use:
    final StringBuilder out = new StringBuilder();
    final Iterator<Foo> it = collection.iterator();
    if (it.hasNext()) {
    out.append(it.next());
    }
    while (it.hasNext()) {
    out.append(separator);
    out.append(it.next());
    }

    Or, if I'm not concerned with efficiency, which is usually the case:
    final StringBuilder out = new StringBuilder();
    for (Foo foo: collection) {
    if (out.size() != 0) {
    out.append(separator);
    }
    out.append(foo);
    }

    All of these are pretty standard idioms. Unless you use a utility
    method somewhere, I don't think you'll get much smaller than that.

    In python I use ", ".join(myStrings) :), although I never use python.


    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, Jun 14, 2008
    #8
  9. Roedy Green

    Roedy Green Guest

    On Fri, 13 Jun 2008 12:20:55 GMT, Roedy Green
    <> wrote, quoted or indirectly quoted
    someone who said :

    >Lets say you want to create a list of items separated by something
    >e.g. comma <BR> \n etc, but you don't want a terminator.
    >
    >How do you go about constructing it with minimal fuss?
    >--


    I have taken your various suggestions and canonicalised them into 7
    methods that all use the same parms and naming conventions. They are
    posted at http://mindprod.com/jgloss/separator.html
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jun 16, 2008
    #9
  10. Roedy Green

    Roedy Green Guest

    On Thu, 19 Jun 2008 01:44:43 +0200, Piotr Kobzda <>
    wrote, quoted or indirectly quoted someone who said :

    >Note that join3() for some input may give different result than the
    >other methods, for example:
    >
    >List<String> input = Arrays.asList( "", "X", "" );
    >
    >join2( input, "|" ) --> "|X|"
    >join3( input, "|" ) --> "X|"
    >
    >
    >Note also, that join1() will fail for zero-element list and non-empty
    >separator input. To correct it trim off the last separator
    >only when sb.length() > 0.
    >
    >
    >Oh, and if you're still collecting them, here is another approach:
    >
    >public static String join(String[] a, String sep) {
    > StringBuilder sb = new StringBuilder();
    > if (a.length > 0) {
    > for (int i = 0;;) {
    > sb.append(a);
    > if (++i == a.length) break;
    > sb.append(sep);
    > }
    > }
    > return sb.toString();
    >}


    I added your method, canonicalised to use the same parms as the
    others.

    I corrected one of the flaws you discovered. If I corrected the other
    flaw it turns into one of the other methods, so I left it as is, just
    documented it.

    I added two tests to the harness to check your corner cases..

    You can see the results at http://mindprod.com/jgloss/separator.html
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jun 20, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Javier
    Replies:
    5
    Views:
    1,025
    Gunnar Hjalmarsson
    Jan 16, 2004
  2. Kevin Spencer

    Re: Separator in panel

    Kevin Spencer, Aug 20, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    423
    Kevin Spencer
    Aug 20, 2003
  3. DC Gringo
    Replies:
    3
    Views:
    6,155
    mikeb
    Aug 19, 2004
  4. Kaja
    Replies:
    0
    Views:
    608
  5. hansiman
    Replies:
    1
    Views:
    19,432
    =?Utf-8?B?S2VuIENveCBbTWljcm9zb2Z0IE1WUF0=?=
    Oct 8, 2004
Loading...

Share This Page