我有一些书籍和出版日期的清单,必须按照以下格式设置
Book Date Book Date
ABC.....12-18 1ABC....12-18
ABCD....12-18 ABC123..12-18
ABCDEF..12-18 ABz.....12-18
X.......12-18 ABCzz...12-18
AIJKL...12-18 ABCdfs..12-18
ABC.....12-18 1ABC....12-18
ABCD....12-18 ABC123..12-18
ABCDEF..12-18 ABz.....12-18
X.......12-18 ABCzz...12-18
AIJKL...12-18 ABCdfs..12-18
我尝试过stringbuilder
List<Book> lstBooks = GetBooks();
StringBuilder books = new StringBuilder();
books = books.AppendLine(" Book Date Book Date ");
foreach (Book b in lstBooks )
{
books.Append(b.Name + ".....".PadLeft(5 - b.CompletedDate.Length) + Environment.NewLine);
}
但是,我很难坚持并排显示数据,我们将不胜感激。
答案 0 :(得分:4)
PadRight
添加足够的'{{1} }'字符,使文本与示例中的文本左对齐。.
左对齐文本,使用PadRight
右对齐文本。PadLeft
和PadLeft
的参数是最大字符串长度 ,而不是要添加的填充字符的数量。PadRight
以确保所有输出均为5个字符(为避免歧义,您应使用ISO 8601格式,并始终避免使用两位数的年份)。MM-yy
答案 1 :(得分:3)
因此,我将为您提供一个选项,您需要对其进行扩展以适用于 all 方案,但是如果您愿意的话,它应该可以助您一臂之力。我还使用字符串列表作为简单示例;您将它应用于Book
上应该没有问题。
您只有一个项目清单,需要在两列中显示,因此您可以将原始内容一分为二,然后Zip
进行备份;像这样:
var strings = new List<string>
{
"first",
"second",
"third",
"fourth"
};
var half = strings.Count / 2;
strings
.Take(half)
.Zip(strings.Skip(half), (f, s) => $"{f} : {s}")
.ToList()
.ForEach(Console.WriteLine);
输出:
第一名:第三名
第二:第四
跟进:当元素数量奇数时会发生什么?
答案 2 :(得分:2)
以列格式输出项目列表的一种方法是确定行数(通过将项目计数除以列计数,如果计数不能被列数均匀除,则加1),然后然后输出格式化为列宽的项目“列数”。
我们可以编写一个方法,该方法接受字符串列表,然后将字符串输出到特定宽度的列中:
public static void OutputInColumns(List<string> items, int columnCount,
int columnWidth, string header = null)
{
// If no columns or no items are specified, return
if (columnCount == 0 || items?.Any() != true) return;
var count = items.Count;
// Determine how many rows we need and fill in last row with empty values if needed
var rows = count / columnCount + (count % columnCount > 0 ? 1 : 0);
items.AddRange(Enumerable.Range(0,
columnCount - count % columnCount).Select(x => string.Empty));
// Output our column headers
if (!string.IsNullOrEmpty(header))
Console.WriteLine(string.Join(" ║ ",
Enumerable.Range(0, columnCount)
.Select(x => header.PadRight(columnWidth, ' '))));
// Output a divider
if (!string.IsNullOrEmpty(header))
Console.WriteLine(string.Join("═╬═",
Enumerable.Range(0, columnCount)
.Select(x => new string('═', columnWidth))));
// Output our row data
for (int row = 0; row < rows; row++)
{
// For each row, add a line with items separated by a tab
Console.WriteLine(string.Join(" ║ ", items
.Skip(row * columnCount)
.Take(columnCount)
.Select(item => item
.Substring(0, Math.Min(item.Length, columnWidth))
.PadRight(columnWidth, ' '))));
}
}
接下来,我们可以编写一个方法,该方法接受Book
,并以"Title....PublishDate"
格式输出字符串。我们可以让用户传递Title
部分的宽度值,如果未指定宽度,则默认为显示整个标题:
public static string AsColumnString(Book book, int columnWidth = 0)
{
if (columnWidth < 1) columnWidth = book.Title.Length + 8;
var name = book.Title.Substring(0, Math.Min(book.Title.Length, columnWidth - 8))
.PadRight(columnWidth - 5, '.');
var date = book.PublishDate.ToString("MM-yy");
return $"{name}{date}";
}
现在,如果我们有一个图书列表,我们可以轻松地将它们打印在任意数量的列中(我们选择任意列宽):
public static void Main(string[] args)
{
var books = new List<Book>
{
new Book {Title = "Ulysses", PublishDate = DateTime.Parse("February 2, 1922")},
new Book {Title = "Don Quixote", PublishDate = DateTime.Parse("January 16, 1605")},
new Book {Title = "The Great Gatsby", PublishDate = DateTime.Parse("April 10, 1925")},
new Book {Title = "Moby Dick", PublishDate = DateTime.Parse("October 18, 1851")},
new Book {Title = "War and Peace", PublishDate = DateTime.Parse("January 1, 1869")},
new Book {Title = "Hamlet", PublishDate = DateTime.Parse("January 1, 1603")},
new Book {Title = "To Kill a Mockingbird", PublishDate = DateTime.Parse("July 11, 1960")},
new Book {Title = "The Catcher in the Rye", PublishDate = DateTime.Parse("July 16, 1951")},
new Book {Title = "The Hobbit", PublishDate = DateTime.Parse("September 21, 1937")},
new Book {Title = "Fahrenheit 451", PublishDate = DateTime.Parse("October 19, 1953")},
new Book {Title = "The Handmaid's Tale", PublishDate = DateTime.Parse("January 1, 1985")},
};
// Select the longest book title and add '8' for the three dots and the date
var columnWidth = books.Select(b => b.Title.Length).Max() + 8;
var columnCount = 2;
// Create our header for each column
var header = "Book".PadRight(columnWidth - 5) + "Date";
OutputInColumns(books.Select(b => AsColumnString(b, columnWidth)).ToList(),
columnCount, columnWidth, header);
}
输出
这是另一个示例,仅这次使用4个较窄的列:
// Note we can make our columns smaller and add more of them
columnWidth = 16;
columnCount = 4;
header = "Book".PadRight(columnWidth - 5) + "Date";
OutputInColumns(books.Select(b => AsColumnString(b, columnWidth)).ToList(), columnCount,
columnWidth, header);
输出
旁注:您可能希望将全年显示为日期,因为我使用的样本跨越多个世纪,所以最后两位数字不是很有用。 :)
答案 3 :(得分:1)
执行以下操作:
static void Main(string[] args)
{
List<Book> lstBooks = GetBooks();
StringBuilder books = new StringBuilder();
books = books.AppendLine("Book Date Book Date");
string dots = "........";
foreach (Book b in lstBooks)
{
string neededDots = dots;
for (int i = 1; i <= b.Name.Length; i++)
{
if (i > 0 && neededDots.Length > 1)
{
neededDots = neededDots.Remove(0, 1);
}
}
books.AppendLine(b.Name + neededDots.PadLeft(5 - b.CompletedDate.Length) + b.CompletedDate
+ " "
+ b.Name + neededDots.PadLeft(5 - b.CompletedDate.Length) + b.CompletedDate);
}
Console.WriteLine(books);
Console.Read();
}
输出:
Book Date Book Date
ABC.....12-18 ABC.....12-18
ABCD....12-18 ABCD....12-18
ABCDEF..12-18 ABCDEF..12-18
X.......12-18 X.......12-18
AIJKL...12-18 AIJKL...12-18
ABC.....12-18 ABC.....12-18
ABCD....12-18 ABCD....12-18
ABCDEF..12-18 ABCDEF..12-18
X.......12-18 X.......12-18
AIJKL...12-18 AIJKL...12-18
答案 4 :(得分:0)
考虑其他答案-我将使用索引方法提供For-Loop。
使用模拟数据定义类型
public class Book
{
public string Name { get; set; }
public DateTime CompletedDate { get; set; }
}
List<Book> lstBooks = new List<Book>
{
new Book { Name = "ABC", CompletedDate = DateTime.Now },
new Book { Name = "1ABC", CompletedDate = DateTime.Now },
new Book { Name = "XYZ", CompletedDate = DateTime.Now },
new Book { Name = "2XYZ", CompletedDate = DateTime.Now },
new Book { Name = "123ABC", CompletedDate = DateTime.Now },
};
示例代码
StringBuilder sBuilder = new StringBuilder();
string completedDateFormat = "MM-dd";
var spacePadding = 4;
var bookDatePadding = Math.Max(5, lstBooks.Max(b => b.Name.Length)) + 1;
var dateSpacePadding = completedDateFormat.Length;
string title = string.Join(string.Empty.PadRight(spacePadding, ' '),
string.Join(string.Empty, "Book".PadRight(bookDatePadding, ' '), "Date".PadRight(dateSpacePadding, ' ')),
string.Join(string.Empty, "Book".PadRight(bookDatePadding, ' '), "Date".PadRight(dateSpacePadding, ' ')));
sBuilder.AppendLine(title);
for (int i = 1, max = lstBooks.Count; i < max; i += 2)
{
sBuilder.AppendLine(string.Join(string.Empty.PadRight(spacePadding, ' '),
string.Join(string.Empty, lstBooks[i - 1].Name.PadRight(bookDatePadding, '.'), lstBooks[i - 1].CompletedDate.ToString(completedDateFormat)),
string.Join(string.Empty, lstBooks[i].Name.PadRight(bookDatePadding, '.'), lstBooks[i - 1].CompletedDate.ToString(completedDateFormat))));
}
// Determine if Last record is accounted for by loop logic by looking at the remainder of a modular operation
var appendLastRecord = lstBooks.Count % 2 != 0;
if (appendLastRecord)
sBuilder.AppendLine(string.Join(string.Empty, lstBooks.Last().Name.PadRight(bookDatePadding, '.'), lstBooks.Last().CompletedDate.ToString(completedDateFormat)));
Console.Write(sBuilder.ToString());
这将输出以下内容
Book Date Book Date
ABC....10-24 1ABC...10-24
XYZ....10-24 2XYZ...10-24
123ABC.10-24
For-Loop将i
定义为索引上的迭代器;
1
,我们将为lopp的每次迭代添加2
,直到i
大于max
,或者-名单。 (i - 1
代表较早的记录,i
将代表较早的记录(甚至是记录,但请注意,在0索引数组中)由于这种方法,我们有一个场景,其中最后一个记录可能不会在循环中表示-很好,因为此循环的主体被设计为一次始终处理2条记录,因此我们需要处理该事件中的一条记录。
包括填充逻辑(尽管此答案的目的是提出for-loop索引方法,不一定提供完整的\工作示例)