0

Is there a way using LINQ, to find if string from one array of strings contains (partial) string from another array of strings? Something like this:

string[] fullStrings = { "full_xxx_part_name", "full_ccc_part_name", "full_zzz_part_name" };
string[] stringParts = { "a_part", "b_part", "c_part", "e_part" }; 

// compare fullStrings array with stringParts array
// full_ccc_part_name contains c_part (first match is OK, no need to find all)
// return index 1 (index 1 from fullStrings array)

This is asked rather for educational purpose. I'm aware that Linq does not magically avoid the loop, instead does it in the background.

1
  • 4
    what is the problem of a loop? In fact when you need to do some list-operation you have to loop that list in some way, be it explictely using a for or whatever-loop or implicetly via some linq-statement. Commented Apr 21, 2021 at 8:20

2 Answers 2

1

You can use Where + Any with string methods:

string[] matches = fullStrings
     .Where(s => stringParts.Any(s.Contains))
     .ToArray();

If you want to compare in a case insensitive way use IndexOf:

string[] matches = fullStrings
     .Where(s => stringParts.Any(part => s.IndexOf(part, StringComparison.OrdinalIgnoreCase) >= 0))
     .ToArray();

In case you want the indexes:

int[] matches = fullStrings 
     .Select((s, index) => (String: s, Index: index))
     .Where(x => stringParts.Any(x.String.Contains))
     .Select(x => x.Index)
     .ToArray();
Sign up to request clarification or add additional context in comments.

11 Comments

The desired answer is the index of the first matching fullStrings item (see // in the code block)
The problem with users that ask these kind of question is they often do not realize a loop is used internally and tend to use linq everywhere in their code without any actual need for it. I agree your assumption, though.
^^ ... or they even think they are being automagically "more efficient".
I suppose we all have made this assumption at some time, though :|
Thank you for the answer. Yes, the question was for educational purposes rather than resolving a real problem. I'm completely aware, that this only hides the loop. And one more time thanks everybody, didn't expect so many comments so quickly. I'm grateful for that.
|
1

You would of course need to use some type of loop to find the index. Here is a solution using Linq. This will return the first index if a match is found or -1 if none is found:

var index = fullStrings
              .Select((s,i) => (s, i))
              .Where(x => stringParts.Any(x.s.Contains))
              .Select(x => x.i)
              .DefaultIfEmpty(-1)
              .First();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.