U4-4670 - Add .ContainsAny string extension to Umbraco.Core.StringExtensions

Created by Jeavon Leopold 10 Apr 2014, 14:00:46 Updated by Shannon Deminick 17 Apr 2014, 00:46:38

Unless it's in a different namespace already, this really useful string extension from DynamicNode is missing in Umbraco.Core.StringExtensions

public static bool ContainsAny(this string haystack, List needles) { if (!string.IsNullOrEmpty(haystack) || needles.Count > 0) { foreach (string value in needles) { if (haystack.Contains(value)) return true; } } return false; }

Original blog post where it is described http://umbraco.com/follow-us/blog-archive/2011/3/13/umbraco-razor-feature-walkthrough-part-5.aspx


Jeavon Leopold 10 Apr 2014, 14:04:40

Ah wait, I found it in Umbraco.Core.Dynamics.ExtensionMethods but is marked as obsolete, couldn't/shouldn't it be moved to StringExtensions?

Stephan 10 Apr 2014, 14:04:56

The method is defined in Umbraco.Core.Dynamics.ExtensionMethods so... it exists. But it is marked obsolete and I don't know why.

Stephan 10 Apr 2014, 14:06:40

Since every method in there has been marked Obsolete by Shannon, I'm reassigning this to him. Shannon: any reason why it's Obsolete? Can we move these methods to StringExtensions?

Jeavon Leopold 10 Apr 2014, 14:11:29

Cool, I don't see what it's got to do with dynamics but it's very useful for MNTP, e.g.

var myMntpPicker = "1234,5678".Split(','); var myThing = Model.Content.Children.Where(x => x.GetPropertyValue("a").ContainsAny(myMntpPicker));

Jeavon Leopold 11 Apr 2014, 09:21:15

Thinking about, maybe something like this is more useful:

public static bool CsvContains(this string valueCsvIds, string valueId) { if (string.IsNullOrEmpty(valueCsvIds)) { return false; } var idCheckList = valueCsvIds.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); return idCheckList.Contains(valueId); }

Then you can find nodes that have the item selected in the MNTP picker

var myCollection = Model.Content.AncestorOrSelf(1).DescendantsOrSelf().Where(x => x.GetPropertyValue("banner").CsvContains("1076"));

Food for thought....

Shannon Deminick 16 Apr 2014, 06:58:33

I've added a simplfied version of this to StringExtensions which is now used by these obsoleted ones. they are obsolete because they were only used for legacy code which will be removed eventually - was just part of the migration process for getting the project structure correct.

Anyways, there's one new method (no need for multiple overloads):

    public static bool ContainsAny(this string haystack, IEnumerable<string> needles, StringComparison comparison = StringComparison.CurrentCulture)
        if (haystack == null) throw new ArgumentNullException("haystack");
        if (string.IsNullOrEmpty(haystack) == false || needles.Any())
            return needles.Any(value => haystack.IndexOf(value) >= 0);
        return false;

Jeavon Leopold 16 Apr 2014, 21:40:07

Looks much better!

What do make of my suggestion above, I'm not sure if CsvContains is the right naming...?

Shannon Deminick 17 Apr 2014, 00:46:38

Sure! Have added that now too.

Priority: Normal

Type: Bug

State: Fixed

Assignee: Shannon Deminick

Difficulty: Normal


Backwards Compatible: True

Fix Submitted:

Affected versions:

Due in version: 6.2.0, 7.1.2


Story Points: