1

This may be a sub-question to this SO Question. I want to check the string against an array of string or list. Example

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();

the purpose is to strip the extra address details after the avenue, the csv file contains all USPS accepted street type.

This is what I have now

//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;       
});

I've been looking for hours how to resolve this then I came across the SO question which is exactly what I also want but I need to get the substring to for stripping.

If there's a linq query, that would be awesome. The only way I can think of doing this is with foreach and inner if.

Example of the array values

  • ave
  • avenue
  • pkwy

Update:

Here is my answer, I forgot to mention that the array lookup needs to match the exact string from the address string. I ended up using regex. This is the expanded/modified answer of @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);

Can somebody convert this to lambda expression? I tried I failed.

Thank you all

CyberNinja
  • 872
  • 9
  • 25
  • 5
    Please show some example lines of data from the csv file and desired output. It will make it easier to understand – Gilad Green Sep 13 '18 at 16:13
  • Just as a warning, linq to SQL from EF may not work with some complex linq queries. – Pac0 Sep 13 '18 at 16:13
  • 1
    Still not clear what you want. Given a collection of values you want to find if they exist in a given string and if so then what? – Gilad Green Sep 13 '18 at 16:15
  • @GiladGreen I search the string with the any of the values in the array then if found, I want to get the substring, so I can remove all other extra details after the street type. – CyberNinja Sep 13 '18 at 16:18
  • OP wants to check if a string contains any value from the array, if yes, wants that value i.e. substring from the array too. –  Sep 13 '18 at 16:18
  • So you want from the beginning until the index of that streetType if present? – Gilad Green Sep 13 '18 at 16:18
  • 1
    Please replace your file access code with a simple `List` initialized with data. In other words, provide a *reproducible*, copy-pasteable sample that we can all use so we're on the same page. – Rufus L Sep 13 '18 at 16:20
  • @GiladGreen yessir – CyberNinja Sep 13 '18 at 16:20

3 Answers3

3

Use IndexOf to understand of item is present in address and if so to return the string after it:

var result = from item in streetType
             let index = address.IndexOf(item)
             where index != -1
             select address.SubString(0, index);
CyberNinja
  • 872
  • 9
  • 25
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
0

One way to do this would be to simply Split each address on the streetType list, and then take the first item (at index[0]) from the resulting array:

addresses = addresses
    .Select(address => address.Split(streetTypes.ToArray(), StringSplitOptions.None)[0])
    .ToList();
Rufus L
  • 36,127
  • 5
  • 30
  • 43
0

I might be inclined to do something like this:

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 }

Then result is an object that is either null (if the marker is not found) or is an object containing both markerIndex, which tells you which marker was found first, and addressPosition which tells you the character at which the marker string was found.

Wyck
  • 10,311
  • 6
  • 39
  • 60