0

I want to concatenate multiple strings together but shown in a neat way.

Example

Record[1]    Title : xxxxxx      Date : dd/mm/yy
Record[1000]    Title : xxxxxx       Date : dd/mm/yy

If i just concatenate the strings together as the record number increases the Title and Date would be pushed across the screen looking messy(shown above). I want the Title and Date to always start at certain position (say position 25) in the string so no matter the number of the record length is the Title and Date will align down the page.

This string will update the Treeview node text.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
AndrewH
  • 59
  • 2
  • 8
  • Unlike forum sites, we don't use "Thanks", or "Any help appreciated", or signatures on [so]. See "[Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). – John Saunders May 23 '14 at 05:45

3 Answers3

3

Consider using composite formatting, specifically the alignment parameter of the format string.

The optional alignment component is a signed integer indicating the preferred formatted field width. If the value of alignment is less than the length of the formatted string, alignment is ignored and the length of the formatted string is used as the field width. The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative. If padding is necessary, white space is used. The comma is required if alignment is specified.

var s="";
foreach (var item in col) {
    s += String.Format("Record[{0,-6}]    Title: {1,-15}    Date: {2}", item.ID, item.Title, item.Date);
}

Example using StringBuilder for effeciency:

var sb = new StringBuilder();
foreach (var item in col) {
    sb.AppendFormat("Record[{0,-6}]    Title: {1,-15}    Date: {2}", item.ID, item.Title, item.Date);
}
Zev Spitz
  • 13,950
  • 6
  • 64
  • 136
  • 2
    Composite formatting is a good approach, but you'll want to use a `StringBuilder` if there's more than a few lines. – John Feminella May 23 '14 at 05:02
  • @JohnFeminella More like a few thousand lines, or extremely long concatenations (not what is happening in this case). It's important to [profile and benchmark, and not just to blindly use](http://stackoverflow.com/a/530014/111794) `StringBuilder`. – Zev Spitz May 23 '14 at 05:12
  • 1
    There are at least 1,000 lines, judging by the OP's example. Also, the source you cited agrees with me: "Definitely use StringBuilder when you're concatenating in a non-trivial loop - **especially if you don't know for sure (at compile time) how many iterations** you'll make through the loop." – John Feminella May 23 '14 at 05:22
1

You can use PadRight() to ensure your first string has the right length:

var record = "Record[1]";
var title = "Title : xxxxxx Date : dd/mm/yy .";

var output = record.PadRight(25) + title;
Mattias Åslund
  • 3,877
  • 2
  • 18
  • 17
1

This works for me:

var paddingRecord = items.Select(x => x.Record.ToString().Length).Max();
var paddingTitle = items.Select(x => x.Title.Length).Max();

var result =
    String.Join(Environment.NewLine,
        items.Select(x =>
            String.Format(
                "Record[{0}]{1} Title : {2}{3} Date : {4:dd/MM/yy}",
                x.Record,
                "".PadLeft(paddingRecord - x.Record.ToString().Length),
                x.Title,
                "".PadLeft(paddingTitle - x.Title.Length),
                x.Date)));

I get this for result:

Record[1]    Title : Foo     Date : 23/05/14
Record[1000] Title : Foo Bar Date : 23/05/14
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • Why do I need both `String.Format` and `PadLeft`? Either one separately will do the job. – Zev Spitz May 23 '14 at 05:15
  • 1
    @ZevSpitz - Because the padding is outside of the square brackets for the first item and because the padding is variable in both cases meaning you'd have to use a double `String.Format` to make the padding work. – Enigmativity May 23 '14 at 05:18
  • 1
    Keep in mind that the collection is being iterated over 3 times, and may be inefficient for very large collections, or where each iteration gets the current item from some external source (say a DB query or network request). – Zev Spitz May 23 '14 at 05:24
  • I would generate the format string once before the `Select`, and then you don't need calls to `PadLeft`. But +1 for `String.Join`. – Zev Spitz May 23 '14 at 05:26
  • 1
    @ZevSpitz - Thanks for the comments. Keep in mind that performance is never going to be an issue for this code. If the OP has that much data then the original query and/or saving the results will be orders of magnitude slower than the code in my answer. – Enigmativity May 23 '14 at 05:30