0

I want to sort elements of a HashSet<string> and join them by a ; character.

Python interpreter version:

>>> st = {'jhg', 'uywer', 'nbcm', 'utr'}
>>> strng = ';'.join(sorted(s))
>>> strng
'ASD;anmbh;ashgg;jhghjg'

C# signature of a method I seek:

private string getVersionsSorted(HashSet<string> versions);

I can do this without using Linq, but I really want to learn it better.

Many thanks!

0

4 Answers 4

3

Note that HashSets are unordered.

Simple slower version:

String.Join(";", versions.OrderBy(v => v).ToArray());

Custom faster version:

versions.OrderBy(v => v).Join(";");

///<summary>Appends a list of strings to a StringBuilder, separated by a separator string.</summary>
///<param name="builder">The StringBuilder to append to.</param>
///<param name="strings">The strings to append.</param>
///<param name="separator">A string to append between the strings.</param>
public static StringBuilder AppendJoin(this StringBuilder builder, IEnumerable<string> strings, string separator) {
    if (builder == null) throw new ArgumentNullException("builder");
    if (strings == null) throw new ArgumentNullException("strings");
    if (separator == null) throw new ArgumentNullException("separator");

    bool first = true;

    foreach (var str in strings) {
        if (first)
            first = false;
        else
            builder.Append(separator);

        builder.Append(str);
    }

    return builder;
}
///<summary>Combines a collection of strings into a single string.</summary>
public static string Join(this IEnumerable<string> strings, string separator) { return new StringBuilder().AppendJoin(strings, separator).ToString(); }

Cute Faster Version

versions.OrderBy(v => v).Aggregate(new StringBuilder(), 
    (v, sb) => sb.Append(sb.Length > 0 ? ";" : "").Append(v)
).ToString();

.Net 4.0 fastest version:

String.Join(";", versions.OrderBy(v => v));
Sign up to request clarification or add additional context in comments.

Comments

3

If you have the option of using .NET 4.0, you could be using the SortedSet<T> class to begin with, which would simplify things greatly, as you just need to call string.Join on your set then.

Otherwise, if you are restricted to .NET 3.5 as it seems, try the following:

private string GetVersionsSorted(ISet<string> versions)
{
    return string.Join(",", versions.OrderBy(s => s).ToArray());
}

(Note: if you were using .NET 4.0 you can also leave out the call to ToArray, which is handy.)

5 Comments

By the way, where does ISet<string> come from? This is what in-VS2008 help gives me: public class HashSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, ISerializable, IDeserializationCallback
ISet<T> is new to .Net 4.0.
Oops, yeah. ISet<T> is new to .NET 4.0 too... I forgot how much of the code I write these days is not backwards compatible with earlier versions of .NET heh! You can get away with using IEnumerable<T> though...
What are the advantages of having ISet<T>? Why did MSFT introduce it? Because it specifies the type more precisely?
@Hamish: It's for a similar reason as ICollection<T> and IList<T>. It represents a common interface (contract) for all set-like classes. It becamse particularly relevant when the BCL got HashSet and SortedSet, so they can have a common basis.
2
HashSet<string> hash = new HashSet<string>(new string[] { "b", "a", "d" });
string output = hash.OrderBy(str => str).Aggregate((a, b) => a + ";" + b);

output: a;b;d

Comments

0
var versions = new HashSet<string>(new[] { "jhg", "uywer", "nbcm", "utr" });
var result = string.Join(";", versions.OrderBy(x => x).ToArray());
Console.WriteLine(result);

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.