У меня есть список таких строк, как:
- Строка1
- String1.String2
- String1.String2.String3
- Другое1
- Другое1.Другое2
- Test1
- Stuff1.Stuff1
- Text1.Text2.Text3
- Folder1.Folder2.FolderA
- Folder1.Folder2.FolderB
- Folder1.Folder2.FolderB.FolderC
Теперь я хотел бы сгруппировать это в:
- String1.String2.String3
- Другое1.Другое2
- Test1
- Stuff1.Stuff1
- Text1.Text2.Text3
- Folder1.Folder2.FolderA
- Folder1.Folder2.FolderB.FolderC
Если "String1" находится в следующем элементе "String1.String2", я проигнорирую первый, а если второй элемент находится в третьем, я возьму только третий "String1.String2.String3" и так далее (n элементов). Строка структурирована как узел / путь и может быть разделена точкой.
Как вы можете видеть в примере с папкой, в папке Folder2 есть два разных элемента вложенных папок, поэтому мне понадобятся обе строки.
Вы знаете, как справиться с этим с помощью Linq? Я бы предпочел VB.Net, но C # тоже подойдет.
С уважением, Ату
Ответ 1 · MarcinJuraszek
Dim r = input.Where(Function(e, i) i = input.Count - 1 OrElse Not input(i + 1).StartsWith(e + ".")).ToList()
Условие в методе Where проверяет, является ли элемент последним от ввода или за ним не следует элемент, содержащий текущий.
В этом решении используется тот факт, что ввод - List(Of String), поэтому Count и input(i+1) доступны в O(1) время.
Ответ 2 · Daniel Hilgarth
LINQ здесь не совсем правильный подход, потому что вам нужно получить доступ к более чем одному элементу одновременно.
Я бы сказал что-то вроде этого:
public static IEnumerable<string> Filter(this IEnumerable<string> source)
{
string previous = null;
foreach(var current in source)
{
if(previous != null && !current.Contains(previous))
yield return previous;
previous = current;
}
yield return previous;
}
Использование:
var result = strings.Filter();
Ответ 3 · Jan P.
Довольно простой. Попробуй это:
var lst = new List<string> { /*...*/ };
var sorted =
from item in lst
where lst.Last() == item || !lst[lst.IndexOf(item) + 1].Contains(item)
select item;
Ответ 4 · Vamsi
следующая простая строка может помочь, я не уверен в стоимости производительности через
List<string> someStuff = new List<string>();
//Code to the strings here, code not added for brewity
IEnumerable<string> result = someStuff.Where(s => someStuff.Count(x => x.StartsWith(s)) == 1);