Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Linq для разделения / анализа подстрок

Автор вопроса: AthuОтветов: 4

У меня есть список таких строк, как:

  • Строка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 # тоже подойдет.

С уважением, Ату

stringlinqgroup-bysplit

Ответы

Ответ 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);

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы