Разделить список строк linq назад для поисковой модели - PullRequest
1 голос
/ 15 января 2020

Извиняюсь, если это плохо сформулировано. Я пытаюсь создать поисковую модель на основе списка строк, используя linq. В каждой строке есть выборка идентификаторов из разных таблиц, и в строке, которую я пытаюсь отфильтровать, основываясь на них. Строка - это то, что вызывает у меня путаницу, так как мне нужно разделить строку, используя _, но от конца строки назад, так как у меня больше контроля с конца строки, чем с начала, так как начало строки 'Name' может содержат много _

Структура строк:

Name_specific_SiteID_CountryID_PageID_DeviceID_PageName

Linq и модель поиска

var result = (from a in context.Searchstrings
              where a.Name.Contains("_specific_")
              select a).ToList().AsQueryable();

if (searchModel != null)
{
    if (searchModel.SiteId.HasValue)
        result = result.Where(p => p.Name.Split('_').Count() - 5 == searchModel.SiteId);

Неопределенный пример - Точка расщепления Строка должна использовать раскрывающиеся списки с идентификатором, совпадающим с позицией в строке - поэтому для SiteID я пытаюсь разделить его и сопоставить searchModel.SiteId с SiteID из раскрывающегося списка в позиции независимо от _specific_ {SiteID } _ остаток строки

Ответы [ 5 ]

2 голосов
/ 15 января 2020

Вы можете реализовать расширение string для добавления пользовательской версии Split(), которая будет работать в обратном направлении:

public static class MyExtension
{
    // input is the input string to split
    // limit is the number of desired substrings to output
    public static IEnumerable<string> ReverseSplit(this string input, int limit = 6)
    {
        var temp = new StringBuilder();

        for (int i = input.Length - 1; i >= 0; i--)
        {
            if (input[i] == '_' && limit > 1)
            {
                yield return temp.ToString();
                temp.Clear();
                limit--;
            }
            else
            {
                temp.Insert(0, input[i]);
            }
        }

        // return the last element
        if (temp.Length > 0)
            yield return temp.ToString();
    }
}

Тестовая программа:

var input = "Name_with_underscore_specific_SiteID_CountryID_PageID_DeviceID_PageName";

foreach (var data in input.ReverseSplit())
{
    Console.WriteLine(data);
}

Это выводит:

PageName
DeviceID
PageID
CountryID
SiteID
Name_with_underscore_specific

Попробуйте сами

1 голос
/ 15 января 2020

Поскольку вы обрабатываете список имен, содержащий подстроку _specific_, вы можете разделить на "_specific_", а затем разделить на '_':

var result = (from a in context.Searchstrings
                where a.Name.Contains("_specific_")
                select a).ToList().AsQueryable();

if (searchModel != null)
{
    if (searchModel.SiteId.HasValue)
        result = result.Where(p => p.Name
            .Split("_specific_", StringSplitOptions.None).Last()
            .Split('_')[0] == searchModel.SiteId);
}

Первые Split преобразуют Name_specific_SiteID_CountryID_PageID_DeviceID_PageName в Name и SiteID_CountryID_PageID_DeviceID_PageName.

Причина, по которой я использовал .Last вместо [1], заключается в том, что если есть вероятность, что Name содержит _specific_, .Split("_specific_", StringSplitOptions.None)[1] даст вам неправильное выход.

1 голос
/ 15 января 2020

Я бы сделал это следующим образом:

string text = "Name_specific_SiteID_CountryID_PageID_DeviceID_PageName";

string[] parts = text.Split('_').Reverse().Take(5).Reverse().ToArray();
string name = text.Substring(0, text.Length - parts.Sum(p => p.Length + 1));

Тогда parts - это массив:

SiteID 
CountryID 
PageID 
DeviceID 
PageName 

с parts[0], являющимся SiteID, и именем, являющимся Name_specific.

0 голосов
/ 15 января 2020

просто небольшая поправка, поскольку вы хотели бы что-то сделать с различными строками, которые вы получаете после разбиения исходной строки.

string name = "Name_specific_SiteID_CountryID_PageID_DeviceID_PageName";
var splittedName = name.Split('_').Reverse();

Затем вы можете делать все, что захотите, с помощью splittedName.

var siteId = splittedName[4]
0 голосов
/ 15 января 2020

У Linq есть Обратный метод

string name = "Name_specific_SiteID_CountryID_PageID_DeviceID_PageName";
name.Split('_').Reverse()

приводит к

PageName
DeviceID
PageID
CountryID
SiteID
specific
Name

То есть

var siteId = name[4];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...