Home > Software design >  C# how to find an index of phrase in array of single words
C# how to find an index of phrase in array of single words

Time:11-25

I have an array of words lets say

string[] myWords = { "Arizona", "District", "Court", "is", "located", "at", ".", "District", "court", "closed" };

I need to find an index of phrase "Arizona District Court" so the result should be

result = [0,1,2]

It should ignore the words "District Court" at index [7,8] because its not a phrase it doesn't have Arizona word before District Court, so should be ignored.

What I have tried is this loop

foreach (var word in myWords)
        {
            if (myWords.Any(word.ToLowerInvariant().Contains))
            {
                var wordIndex = word;
            }
        }

but it return all matches for me

CodePudding user response:

You could use this LINQ query using SequenceEqual:

string[] myWords = { "Arizona", "District", "Court", "is", "located", "at", ".", "District", "court", "closed" };
string phraseToFind = "Arizona District Court";
string[] phrases = phraseToFind.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

int[] firstMatchingSequenceIndexes = Enumerable.Range(0, myWords.Length)
    .Where(index => myWords.Skip(index).Take(phrases.Length).SequenceEqual(phrases))
    .Select(index => Enumerable.Range(index, phrases.Length).ToArray())
    .FirstOrDefault();

https://dotnetfiddle.net/wq7Bv0

Explanation:

  • the query checks each index of the myWords-array
  • it takes a sub-sequence of it with Skip(index) and Take(length)
  • it compares this part with the phraseToFind-array
  • if they are equal the matching indexes are returned as int[]
  • change First() to ToArray if you want all matches or Count() if you want the count

Since you have asked, this is how you would get the complete list:

int[][] allMatchingSequenceIndexes = Enumerable.Range(0, myWords.Length)
    .Where(index => myWords.Skip(index).Take(phrases.Length).SequenceEqual(phrases))
    .Select(index => Enumerable.Range(index, phrases.Length).ToArray())
    .ToArray();

If you want to ignore the case, so it doesn't matter if it's "arizona" or "Arizona", use the right StringComparer in SequenceEqual. For example:

.Where(index => .... .SequenceEqual(phrases, StringComparer.OrdinalIgnoreCase))
  • Related