Как добавить уникальные числа в список строк
У меня есть эта функция, которая работает и дает правильный результат:
<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
Эта функция добавляет "2", "3" и т.д. по мере необходимости к тем элементам, которые не уникальны, чтобы сделать их уникальными.
Как удалить регулярное выражение, когда а) останется в одном и том же выражении linq (одна и та же строка кода), b) без введения цикла или c) дважды оценивая выражение, что необходимо в операторе IIF
Это не дубликат Получение индекса повторяющихся элементов в списке в С#, так как a) мой список не изменяется во время функции и b) этот вопрос на него не ответил, готовый применить пример кода, и здесь я ищу конкретное исправление для конкретной строки кода. Эти ответы не будут исправлять мою проблему; они не применяются здесь.
Ответы
Ответ 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
Ответ 2
Здесь версия 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