Assuming you just want to throw away longer values, you can just use the IEqualityComparer<string> implementation to get a new set.
private class ShortestSubStringComparer : IComparer<string>, IEqualityComparer<string> { public int Compare(string x, string y) { if (x == null) return (y == null) ? 0 : -1; if (y == null) return 1; Debug.Assert(x != null && y != null); if (this.Equals(x, y)) return x.Length.CompareTo(y.Length); return StringComparer.CurrentCulture.Compare(x, y); } public bool Equals(string x, string y) { if (x == null) return y == null; if (x.StartsWith(y)) return true; if (y != null && y.StartsWith(x)) return true; return false; } public int GetHashCode(string obj) { return obj.GetHashCode(); } }
And then your function can use the GroupBy function to group and select the first ordered element as follows:
public HashSet<string> FindShortestSubString(HashSet<string> set) { var comparer = new ShortestSubStringComparer(); return new HashSet<string>(set.GroupBy(e => e, comparer).Select(g => g.OrderBy(e => e, comparer).First())); }
Or maybe Min can do the trick (that means you don't need an implementation of IComparer<string> ) ...
public HashSet<string> FindShortestSubString(HashSet<string> set) { var comparer = new ShortestSubStringComparer(); return new HashSet<string>(set.GroupBy(e => e, comparer).Select(g => g.Min(e => e))); }
source share