LINQ搜索有序列表并追加发生编号

LINQ搜索有序列表并追加发生编号,linq,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 myF

我有以下自定义类

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();

我刚刚在专辑类中添加了一个订单

  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);
    }
公共类相册
{
公共字符串名称{get;set;}
公共字符串位置{get;set;}
公共日期时间日期时间{get;set;}
公共整数顺序{get;set;}
}
公共静态字符串解决方案(字符串S)
{
字符串[]字符串分隔符=新字符串[]{“\r\n”};
string[]group=S.Split(StringSeparator、StringSplitOptions.None);
列表=新列表();
StringBuilder sb=新的StringBuilder();
//将字符串的每一行添加到列表中
对于(int i=0;io.Location.ToList();
for(int i=0;ig.Select(h=>h))
托利斯先生()
.OrderBy(y=>y.Order)
.选择(g=>g.PhotoName);
返回字符串。连接(“\r\n”,位置);
}

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

对于手头的任务,不需要一个
相册
类、一个
列表
和两个循环

我们可以检查一下这些行,然后用
字典
为我们保存计数器

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];
    }
}

预期的结果是什么?你能把它贴出来吗?Ofirwingarden我已经在上面说过了。非常有用。这是一个非常基本的表单,您需要在productionHold中使用之前改进代码,抱歉。Warsaw2必须首先出现在Warsaw1之前,因为第一行上的时间戳晚于第三行。只需在GroupBy之前添加一个OrderBy:var groupedByLocation=list.OrderBy(o=>o.DateTime).GroupBy(o=>o.Location.ToList();我更新了我的预期结果,因为它必须按DateTime订购,在您发布后。只是不知道如果我尝试这个,结果是否会一样,但我会尝试
  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);
    }
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);