Проверьте строку, если она содержит какое-либо значение строкового массива, затем получите подстроку

Это может быть подвопрос к этому ТАК вопрос. Я хочу сравнить строку с массивом строк или списком. Пример

string address = "1st nice ave 1st floor";    
//For now, I'm getting the list from a text file but could move to use an EF    
List<string> streetType = File.ReadLines(AppDomain.CurrentDomain.BaseDirectory + @"streetType.csv")
                              .Where(x => x.Length > 0)
                              .Select(y => y.ToLowerInvariant())
                              .ToArray();

цель состоит в том, чтобы удалить дополнительные сведения об адресе после проспекта, файл csv содержит все типы улиц, принятые USPS.

Это то, что у меня есть сейчас

//this only returns boolean value, I got this from the SO above
streetType.Any(testaddress.ToLower().Contains);

//I also have this
Array.Exists<string>(streetType, (Predicate<string>)delegate (string s)
{         
   return testaddress.IndexOf(s, StringComparison.OrdinalIgnoreCase) > -1;       
});

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

Если есть запрос linq, это было бы здорово. Я могу думать об этом только с помощью foreach и внутреннего if.

Пример значений массива

  • авеню
  • проспект
  • pkwy

Обновлять:

Вот мой ответ, я забыл упомянуть, что поиск по массиву должен соответствовать точной строке из адресной строки. В итоге я использовал регулярное выражение. Это расширенный / измененный ответ @giladGreen.

  var result = from item in streetTypes
                         let index = Regex.Match(address.ToLowerInvariant(), @"\b" + item.ToLowerInvariant() + @"\b")
                         where index.Success == true
                         select address.ToLowerInvariant().Substring(0, index.Index + item.Length);

Может ли кто-нибудь преобразовать это в лямбда-выражение? Я пытался, но потерпел неудачу.

Спасибо вам всем

Покажите несколько примеров строк данных из файла csv и желаемого результата. Так будет легче понять

Gilad Green 13.09.2018 18:13

В качестве предупреждения, linq to SQL из EF может не работать с некоторыми сложными запросами linq.

Pac0 13.09.2018 18:13

Все еще не ясно, что вы хотите. Учитывая набор значений, которые вы хотите найти, существуют ли они в данной строке, и если да, то что?

Gilad Green 13.09.2018 18:15

@GiladGreen Я ищу строку с любым из значений в массиве, а затем, если он найден, я хочу получить подстроку, поэтому я могу удалить все остальные дополнительные детали после типа улицы.

CyberNinja 13.09.2018 18:18

OP хочет проверить, содержит ли строка какое-либо значение из массива, если да, хочет это значение, то есть подстроку из массива.

njras 13.09.2018 18:18

Итак, вы хотите от начала до индекса этого streetType, если он присутствует?

Gilad Green 13.09.2018 18:18

Пожалуйста, замените свой код доступа к файлу на простой List<string>, инициализированный данными. Другими словами, предоставьте воспроизводимый, копируемый образец, который мы все можем использовать, чтобы мы были на одной странице.

Rufus L 13.09.2018 18:20

@GiladGreen, да, сэр

CyberNinja 13.09.2018 18:20
1
8
90
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Используйте IndexOf, чтобы понять, что элемент присутствует в address, и если это так, чтобы вернуть строку после него:

var result = from item in streetType
             let index = address.IndexOf(item)
             where index != -1
             select address.SubString(0, index);

Один из способов сделать это - просто Split для каждого адреса в списке streetType, а затем взять первый элемент (в index[0]) из результирующего массива:

addresses = addresses
    .Select(address => address.Split(streetTypes.ToArray(), StringSplitOptions.None)[0])
    .ToList();

Я мог бы сделать что-то вроде этого:

string[] markers = "ave avenue pkwy".Split();
string address = "1st nice ave 1st floor";

var result = markers
            .Select((marker, index) => new
            {
                markerIndex = index,
                addressPosition = address.IndexOf(marker)
            })
            .FirstOrDefault(x => x.addressPosition != -1);


// returns { markerIndex = 0, addressPosition = 9 }

Тогда result - это объект, который является либо нулевой (если маркер не найден), либо является объектом, содержащим как markerIndex, который сообщает вам, какой маркер был найден первым, так и addressPosition, который сообщает вам символ, в котором была найдена строка маркера.

Другие вопросы по теме