如何将唯一数字附加到字符串列表中

时间:2014-11-01 03:06:27

标签: .net linq

我有这个功能,它起作用并给出正确的结果:

  <System.Runtime.CompilerServices.Extension()>
  Public Function Unique(List As List(Of String)) As List(Of String)
    Return List.Select(Function(x, index) x & System.Text.RegularExpressions.Regex.Replace((List.GetRange(0, index).Where(Function(y) y = x).Count + 1).ToString, "\b1\b", String.Empty)).ToList
  End Function

此功能根据需要将&#34; 2&#34;,&#34; 3&#34;等附加到那些不唯一的项目,以使它们唯一。

如何在a)中保留相同的linq语句(相同的代码行),b)不引入循环或c)评估表达式两次,如{{1}中所需要的那样,删除正则表达式声明?

这不是Getting index of duplicate items in a list in c#的副本,因为a)我的列表在功能期间没有变化,而b)该问题没有通过准备应用代码示例来回答,而且我在这里查找对特定代码行的特定修复。这些答案不会解决我的问题;他们不适用于此。

2 个答案:

答案 0 :(得分:1)

您可以使用GroupBy执行此操作,如果要保留原始订单,可以创建一个匿名类型以包含它,然后分组,然后按原始顺序重新排序。

    string[] input = new[]{ "Apple", "Orange", "Apple", "Pear", "Banana", 
                            "Apple", "Apple", "Orange" };

    var result = input
        // Remember the initial order
        .Select((name, i) => new {name, i})
        .GroupBy(x => x.name)
        // Now label the entries in each group
        .SelectMany(g => g.Select((item, j) => 
            new {i = item.i, name = (j == 0 ? item.name : item.name + (j+1))}))
        // Now reorder them by their original order
        .OrderBy(x => x.i)
        // Remove the order value to get back to just the name
        .Select(x => x.name)
        .ToList();


    foreach (var r in result)
        Console.WriteLine(r);

结果

Apple
Orange
Apple2
Pear
Banana
Apple3
Apple4
Orange2

答案 1 :(得分:0)

这是VB版本:

  <System.Runtime.CompilerServices.Extension()>
  Public Function Unique(List As List(Of String)) As List(Of String)
    ' 1. Remember the initial order
    ' 2. Group by the text
    ' 3. Label the entries in each group
    ' 4. Now reorder them by their original order
    ' 5. Remove the order value to get back to just the name
    Return List.
      Select(Function(Item, Index) New With {Item, Index}).
      GroupBy(Function(IndexedItem) IndexedItem.Item).
      SelectMany(Function(Group) Group.Select(Function(GroupItem, GroupIndex) New With {.Index = GroupItem.Index, .UniqueItem = GroupItem.Item & If(GroupIndex = 0, String.Empty, (GroupIndex + 1).ToString)})).
      OrderBy(Function(IndexedUniqueItem) IndexedUniqueItem.Index).
      Select(Function(IndexedUniqueItem) IndexedUniqueItem.UniqueItem).
      ToList()
  End Function