LINQ OrderBy и StringBuilder - PullRequest
       5

LINQ OrderBy и StringBuilder

0 голосов
/ 03 сентября 2018

У меня есть следующий пользовательский класс

public class Album
{
    public string PhotoName { get; set; }
    public string Location { get; set; }
    public DateTime DateTime { get; set; }
}

и у меня есть список того типа, который я отсортировал по местоположению, а затем по дате / времени

List<Album> SortedList = list
  .OrderBy(o => o.Location)
  .ThenBy(o => o.DateTime)
  .ToList();

теперь мне нужно иметь StringBuilder, который будет добавлять индексный номер рядом с местоположением, но индексный номер должен зависеть от местоположения, а не от списка

Например, мой список содержит:

> a | London | 12:00:00 AM
> b | London | 1:00:00 AM
> c | Warsaw | 1:30:00 AM
> d | Warsaw | 1:45:00 AM

Мой StringBuilder должен быть:

> London01
> London02
> Warsaw01
> Warsaw02

Я пытался использовать это, но он возвращает индексный номер списка

var query = SortedList.IndexOf(list.SingleOrDefault(i => i.DateTime == a.DateTime));

Просто хотите узнать, как я могу выполнить свои необходимые требования?

Обновление: Это мой полный код, в который я должен поместить строителя строк:

public static string Solution(string S)
    {
        string[] group = S.Split("\r\n");
        List<Album> list = new List<Album>();
        StringBuilder sb = new StringBuilder();

        foreach (string g in group)
        {
            string[] album = g.Split(',');
            Album a = new Album();
            a.PhotoName = album[0];
            a.Location = album[1];
            a.DateTime = DateTime.Parse(album[2]);
            list.Add(a);
        }

        List<Album> SortedList = list.OrderBy(o => o.Location).ThenBy(o => o.DateTime).ToList();

        foreach (string g in group)
        {
            string[] album = g.Split(',');
            Album a = new Album();
            a.PhotoName = album[0];
            string[] photodetails = a.PhotoName.Split('.');
            a.Location = album[1];
            a.DateTime = DateTime.Parse(album[2]);

  //this is the part where I must figure out how to build the string

           // var query = SortedList.IndexOf(list.SingleOrDefault(i => i.DateTime == a.DateTime));

            sb.AppendLine(a.Location + query + "." + photodetails[1]);

        }

        string res = sb.ToString();
        return res;
    }

строка S имеет вид:

@"photo.jpg, Warsaw, 2013-09-05 14:08:15
john.png, London, 2015-06-20 15:13:22
myFriends.png, Warsaw, 2013-09-05 14:07:13
Eiffel.jpg, Paris, 2015-07-23 08:03:02
pisatower.jpg, Paris, 2015-07-22 23:59:59
BOB.jpg, London, 2015-08-05 00:02:03"

и полученный StringBuilder должен быть

Warsaw01
London01
Warsaw02
Paris01
Paris02
London02

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Вы можете использовать комбинацию GroupBy и Aggregate методов расширения

var output = 
    albums.GroupBy(album => album.Location)
          .OrderBy(group => group.Key)
          .SelectMany(group => group.OrderBy(album => album.DateTime)
                                    .Select((album, i) => $"{album.PhotoName}{(i+1):00}"))
          .Aggregate(new StringBuilder(),
                     (builder, item) => builder.AppendLine(item))
          .ToString();
0 голосов
/ 03 сентября 2018

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

var result = list
              .OrderBy(o => o.Location)
              .ThenBy(o => o.DateTime)
              .GroupBy(o => o.Location)
              .SelectMany(o => o.Select((x,i) => x.Location + (i + 1).ToString("d2")));

А если вы хотите получить строку, нет необходимости в StringBuilder, просто выполните:

var resultString = string.Join("\n", result);
...