Форматирование строки C # с одинаковым интервалом между значениями - PullRequest
30 голосов
/ 24 января 2011

У меня есть 3 строки. Первый набор строк:

"1.0536"  
"2.1"  
"2" 

Второе что-то вроде:

"Round"  
"Square"  
"Hex"

И последние:

"6061-T6"  
"T351"  
"ASF.3.4.5" 

Мне нужно объединить три строки с одинаковым интервалом между каждой строкой. Я не могу использовать \ t для табуляции, так как после объединения строк я отправляю их в базу данных Access.

Когда я объединяю строки, они выглядят так:

"1.0536 Round 6061-T6"  
"2.1 Square T351"  
"2 Hex ASF.3.4.5" 

Мне бы очень хотелось, чтобы они выглядели так же с одинаковым точным интервалом между каждой строкой:

"1,0536 Раунд 6061-T6"
"2.1 Квадрат T351"
"2 Hex ASF.3.4.5"

Как я могу сделать это с C #?

Ответы [ 7 ]

41 голосов
/ 24 января 2011

Вы можете использовать дополнительные функции из string.Format:

string.Format("{0,-10}{1,-10}{2}", ...)

Вы можете сделать то же самое, написав str.PadRight(10)

6 голосов
/ 24 января 2011

Если вы знаете максимальную длину каждого столбца, выполните следующие действия:

String result = String.Format("{0} {1} {2}", strCol1.PadRight(10), strCol2.PadRight(9), strCol3.PadRight(9));
4 голосов
/ 22 мая 2014

Чтобы облегчить жизнь, полезны методы:

Использование

var data = new[] {
    new[] { "ID", "NAME", "DESCRIPTION" },
    new[] { "1", "Frank Foo", "lorem ipsum sic dolor" },
    new[] { "2", "Brandon Bar", "amet forthrightly" },
    new[] { "3", "B. Baz", "Yeehah!" }
};

var tabbedData = EvenColumns(20, data);
var tabbedData2 = string.Join("\n", EvenColumns(20, false, data)); // alternate line separator, alignment

Результаты

ID                  NAME                DESCRIPTION
1                   Frank Foo           lorem ipsum sic dolor
2                   Brandon Bar         amet forthrightly
3                   B. Baz              Yeehah!

ID                NAME         DESCRIPTION
1           Frank Foolorem ipsum sic dolor
2         Brandon Bar   amet forthrightly
3              B. Baz             Yeehah!

код

public string EvenColumns(int desiredWidth, IEnumerable<IEnumerable<string>> lists) {
    return string.Join(Environment.NewLine, EvenColumns(desiredWidth, true, lists));
}

public IEnumerable<string> EvenColumns(int desiredWidth, bool rightOrLeft, IEnumerable<IEnumerable<string>> lists) {
    return lists.Select(o => EvenColumns(desiredWidth, rightOrLeft, o.ToArray()));
}

public string EvenColumns(int desiredWidth, bool rightOrLeftAlignment, string[] list, bool fitToItems = false) {
    // right alignment needs "-X" 'width' vs left alignment which is just "X" in the `string.Format` format string
    int columnWidth = (rightOrLeftAlignment ? -1 : 1) *
                        // fit to actual items? this could screw up "evenness" if
                        // one column is longer than the others
                        // and you use this with multiple rows
                        (fitToItems
                            ? Math.Max(desiredWidth, list.Select(o => o.Length).Max())
                            : desiredWidth
                        );

    // make columns for all but the "last" (or first) one
    string format = string.Concat(Enumerable.Range(rightOrLeftAlignment ? 0 : 1, list.Length-1).Select( i => string.Format("{{{0},{1}}}", i, columnWidth) ));

    // then add the "last" one without Alignment
    if(rightOrLeftAlignment) {
        format += "{" + (list.Length-1) + "}";
    }
    else {
        format = "{0}" + format;
    }

    return string.Format(format, list);
}

Специфично для вопроса

// for fun, assume multidimensional declaration rather than jagged
var data = new[,] {
    { "1.0536", "2.1", "2" },
    { "Round", "Square", "Hex" },
    { "6061-T6", "T351", "ASF.3.4.5" },
};

var tabbedData = EvenColumns(20, Transpose(ToJaggedArray(data)));

с Transpose:

public T[][] Transpose<T>(T[][] original) {
    // flip dimensions
    var h = original.Length;
    var w = original[0].Length;

    var result = new T[h][];
    for (var r = 0; r < h; r++) {
        result[r] = new T[w];
        for (var c = 0; c < w; c++)
        {
            result[r][c] = original[c][r];
        }
    }
    return result;
}

и многомерных массивов ( источник ):

public T[][] ToJaggedArray<T>(T[,] multiArray) {
    // via /2478325/preobrazovanie-mnogomernyh-massivov-v-asp-net
    var h = multiArray.GetLength(0);
    var w = multiArray.GetLength(1);

    var result = new T[h][];
    for (var r = 0; r < h; r++) {
        result[r] = new T[w];
        for (var c = 0; c < w; c++) {
            result[r][c] = multiArray[r, c];
        }
    }
    return result;
}
2 голосов
/ 30 ноября 2017

Я знаю, что на это уже давно дан ответ, но с C # 6.0

string[] one = new string[] { "1.0536", "2.1", "2" };
string[] two = new string[] { "Round", "Square", "Hex" };
string[] three = new string[] { "1.0536 Round 6061-T6", "2.1 Square T351", "2 Hex ASF.3.4.5" };

for (int i = 0; i < 3; i++) Console.WriteLine($"{one[i],-10}{two[i],-10}{three[i],-10}");

существует новый способ. $"{one[i],-10}{two[i],-10}{three[i],-10}" - это новая замена для string.format.Я нашел это очень полезным во многих моих проектах.Вот ссылка на дополнительную информацию о интерполяции строк в c # 6.0: https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/string-interpolation

1 голос
/ 24 января 2011

Чтобы сделать это более динамично, вы можете сделать что-то вроде этого: (жёсткое программирование!)

    int padding = 3;
    int maxCol0width = "Hello World!".Length;
    int maxCol1width = "90.345".Length;
    int maxCol2width = "value".Length;

    string fmt0 = "{0,-" + (maxCol0width + padding) + "}";
    string fmt1 = "{1,-" + (maxCol1width + padding) + "}";
    string fmt2 = "{2,-" + (maxCol2width + padding) + "}";

    string fmt = fmt0 + fmt1 + fmt2;

    Console.WriteLine(fmt, "Hello World!", 90.345, "value");
    Console.WriteLine(fmt, "Hi!", 1.2, "X");
    Console.WriteLine(fmt, "Another", 100, "ZZZ");

Вам, конечно, нужно определить максимальную ширину слова, просматривая значения каждого столбца. Также создание строки формата может быть значительно очищено и сокращено.

1 голос
/ 24 января 2011

Использование String.Format("{0,10}", myString)
Где 10 - это количество символов, которое вы хотите

0 голосов
/ 24 января 2011

Также обратите внимание, что вам нужно будет использовать непропорциональный шрифт для отображения, иначе ваши столбцы все равно не будут правильно выстроены. Где вы отображаете эти данные? Могут быть более эффективные способы получения табличного вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...