1

I've seen examples for doing this using linq like this:

List<string> list = new List<string> {"One", "Two", "Three", "Four", "five", "six" };
string text = "OneTwoThreeFour";

list.Any(s => text.contains(s))

but does this apply for all possible words? meaning, if I have a big word composed of 3 smaller words (not separated by any special character), will it catch all 3 sub-words? or will this stop checking once it's found one match?

what I'm trying to accomplish is to take a word like "OneTwoThreeFour" and add a space or a dash between each unique word so its "One Two Three Four".

Is there a better way to do this?

and is it possible to get the "string" that returned as a match?

Abdul Ahmad
  • 9,673
  • 16
  • 64
  • 127
  • Could you provide an example of what is contained in the list and your `text` ? – Habib Feb 17 '15 at 16:19
  • sure give me a minute – Abdul Ahmad Feb 17 '15 at 16:20
  • What is expected output? – Ehsan Sajjad Feb 17 '15 at 16:34
  • its in the question already, I want to make `OneTwoThreeFour` into `One Two Three Four` – Abdul Ahmad Feb 17 '15 at 16:35
  • Do you have a dictionary of 'all possible words' available at runtime? Are the words indicated by caps? Do you have a plan for distinguishing compound words like 'room' 'plan' and 'roomplan'? – Steve Mitcham Feb 17 '15 at 16:35
  • I think your best bet for producing the desired output is to generate a regular expression on the fly that matches your list: /(One|Two|Three|Four)/. Mind @SteveMitcham 's point about prefixes, though. You might just have to write actual code here. Which would be fun, so NBD. – 15ee8f99-57ff-4f92-890c-b56153 Feb 17 '15 at 16:36
  • @SteveMitcham yes I have a dictionary of possible words that can be in the text. The words are not indicated by caps, otherwise this would be easier. and yes I'd like to distinguish between 'room' 'plan' and 'roomplan' – Abdul Ahmad Feb 17 '15 at 16:40
  • What would your expectations be if you encounter a set of characters that can't be resolved into a word from the dictionary. In your example, if the starting string is "OneTwobhThreeFour", what happens to the "bh" – Steve Mitcham Feb 17 '15 at 16:51

2 Answers2

2

Update to cover either condition:

You can get a list of words from text by adding spaces before capital letters and splitting on space. Then you can compare that result with list using SequenceEqual().

Here's an example:

static void Main(string[] args)
{
    List<string> list = new List<string> {"One", "Two", "Three", "Four", "Five" };
    string text = "OneTwoThreeFourFive";

    string withSpaces = AddSpacesToSentence(text, true);
    List<string> list2 = withSpaces.Split(' ').ToList();

    bool b = list.SequenceEqual(list2);
}

// Refer to: https://stackoverflow.com/a/272929/4551527
static string AddSpacesToSentence(string text, bool preserveAcronyms)
{
    if (string.IsNullOrWhiteSpace(text))
        return string.Empty;
    StringBuilder newText = new StringBuilder(text.Length * 2);
    newText.Append(text[0]);
    for (int i = 1; i < text.Length; i++)
    {
        if (char.IsUpper(text[i]))
            if ((text[i - 1] != ' ' && !char.IsUpper(text[i - 1])) ||
                (preserveAcronyms && char.IsUpper(text[i - 1]) &&
                    i < text.Length - 1 && !char.IsUpper(text[i + 1])))
                newText.Append(' ');
        newText.Append(text[i]);
    }
    return newText.ToString();
}

Note that I got the implementation for AddSpacesToSentence from this answer: https://stackoverflow.com/a/272929/4551527

Another Update

By the way, if the order of the words in the lists is not important (in other words: "OneTwo" should match {"Two","One"}), then you can Sort() both lists before doing the SequenceEquals()


Original (when I thought it was one-way comparison)

You could use All() instead:

List<string> list = new List<string> {"One", "Two", "Three", "Four" };
string text = "OneTwoThreeFour";

list.All(s => text.Contains(s))

This will return true if all elements in the sequence satisfy the predicate (here, contains).

The snippet above returns true. If you add "Five" to list (but leave text the same) then it will return false.

Community
  • 1
  • 1
ama1111
  • 569
  • 3
  • 10
1

A simple approach could be to iterate through the list of items and do String Replace (I have used StringBuilder, you can use String.Replace as well) like:

List<string> list = new List<string> { "One", "Two", "Three", "Four", "five", "six" };
string text = "OneTwoThreeFour";
StringBuilder sb = new StringBuilder(text);
foreach (var str in list)
{
    sb.Replace(str, " " + str + " ");
}

string modifiedText = sb.ToString();

That will give you modifiedText = " One Two Three Four ". As a side note you don't have to check for Any existence of items in the list. If that item doesn't exists in the list, String.Replace will not do anything.

For:

will it catch all 3 sub-words? or will this stop checking once it's found one match?

It will stop once a match is found. You are using Enumerable.Any and as soon as match is found , no further comparison will be performed.

Habib
  • 219,104
  • 29
  • 407
  • 436