LINQ搜索有序列表并附加出现编号

时间:2018-09-03 08:36:59

标签: linq

我有以下自定义课程

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

,我有以下字符串:

@"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.jpg
London01.jpg
Warsaw02.jpg
Paris01.jpg
Paris02.jpg
London02.jpg

到目前为止我做了什么?

我有一个按位置,然后按日期时间排序的类型的列表

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

现在我需要有一个StringBuilder,它将在位置旁边附加索引号。

这是我完成零件的完整方法,我被困在应该如何搜索有序列表中。问题是:如何编写用于搜索列表的LINQ?:

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

    //added each line of the string to list
        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);
        }

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

        //then foreach line, append index number by searching through the list
        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. I am stuck here

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

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

        }

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

感谢您的回应。

更新,因为Warsaw2的时间戳晚于Warsaw1,所以Warsaw2必须出现在Warsaw1之前

Warsaw02.jpg
London01.jpg
Warsaw01.jpg
Paris01.jpg
Paris02.jpg
London02.jpg

2 个答案:

答案 0 :(得分:0)

我刚刚在Album类中添加了订单

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

    public int Order { get; set; }
}

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

        //added each line of the string to list
        for (int i = 0; i < group.Length; i++)
        {
            string[] album = group[i].Split(',');
            Album a = new Album();
            a.PhotoName = album[0];
            a.Location = album[1];
            a.DateTime = DateTime.Parse(album[2]);
            a.Order = i;
            list.Add(a);
        }

        //ordered the list
        var groupedByLocation = list.GroupBy(o => o.Location).ToList();


        for (int i = 0; i < groupedByLocation.Count; i++)
        {
            int indexValue = 01;
            foreach (var item in groupedByLocation[i])
            {
                item.PhotoName = string.Format("{0}{1}.jpg", groupedByLocation[i].Key, indexValue);
                indexValue++;
            }
        }

        //then foreach line, append index number by searching through the list
        var locations = groupedByLocation
                        .SelectMany(g => g.Select(h => h))
                        .ToList()
                        .OrderBy(y => y.Order)
                        .Select(g => g.PhotoName);

        return string.Join("\r\n", locations);
    }

答案 1 :(得分:0)

只是为了好玩-另一种方法:

对于手头的任务,不需要一个Album类,一个list和两个循环。

我们可以跳过这些行一次,并使用dictionary来为我们保留计数器。

class PhotoLocationsCounter
{
    private readonly Dictionary<string, int> locationsCounter = new Dictionary<string, int>();

    public string GetLocationsWithCounters(string source)
    {
        string[] lines = source.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
        var locations = lines.Select(this.LineToLocationWithCounter);

        return string.Join("\n", locations);
    }

    private string LineToLocationWithCounter(string line)
    {
        string[] album = line.Split(',');
        var location = album[1].Trim();
        var ext = album[0].Split('.')[1];
        var counter = this.GetAndIncreaseLocationCounter(location);
        return $"{location}{counter.ToString("D2")}.{ext}";
    }

    private int GetAndIncreaseLocationCounter(string location)
    {
        if (!this.locationsCounter.TryGetValue(location, out int counter))
        {
            this.locationsCounter.Add(location, 0);
        }
        return ++this.locationsCounter[location];
    }
}

您称之为:

string data = @"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";
var locations = new PhotoLocationsCounter().GetLocationsWithCounters(data);