Is it possible for String.split () to return a tuple?

I have a string that I need split() and assign it a value to two variables. Is it possible to split() return tuple instead of string[] so that I can do something like:

 String myString = "hello=world" value, id = myString.Split('='); 

I am looking for an elegant solution.

+5
source share
5 answers

If you can use C # 7, you can use tuple deconstruction. If the type has a static or expansion method named Deconstruct with the corresponding signature, this type can be deconstructed. So you can have an extension method like this:

 public static class Extensions { public static void Deconstruct<T>(this IList<T> list, out T first, out IList<T> rest) { first = list.Count > 0 ? list[0] : default(T); // or throw rest = list.Skip(1).ToList(); } public static void Deconstruct<T>(this IList<T> list, out T first, out T second, out IList<T> rest) { first = list.Count > 0 ? list[0] : default(T); // or throw second = list.Count > 1 ? list[1] : default(T); // or throw rest = list.Skip(2).ToList(); } } 

And then you can decompose the string array (which implements IList<string> ) with this syntax (you may need to add the appropriate using so that the extension method above is available):

 var line = "a=b"; var (first, second, _) = line.Split('='); Console.WriteLine(first); // "a" Console.WriteLine(second); // "b" 

or

 var line = "a=b"; var (first, (second, _)) = line.Split('='); Console.WriteLine(first); // "a" Console.WriteLine(second); // "b" 

This is pretty close to what you need.

Using only the first extension method above (which deconstructs the first element and the rest) you can deconstruct an arbitrary length:

 var (first, (second, _)) = line.Split('='); var (first, (second, (third, _))) = line.Split('='); var (first, rest) = line.Split('='); // etc 

The second extension method is only necessary if you want a slightly more convenient syntax for deconstructing the first two values ​​( var (first, second, rest) instead of var (first, (second, rest)) )

+13
source

Using LinQ:

 List<Tuple<string, string>> pairs = lines .Select(x => { string[] s = x.Split('='); return Tuple.Create(s[0], s[1]); }) .ToList(); 
+2
source

In C # 7, you can use var out and extension to declare and assign multiple variables from an array with a group of extension methods:

 static class MyExtensions { static void Assign<T>(this IList<T> items, out T v) { v = items[0]; } static void Assign<T>(this IList<T> items, out T v0, out T v1) { v0 = items[0]; v1 = items[1]; } static void Assign<T>(this IList<T> items, out T v0, out T v1, out T v2) { v0 = items[0]; v1 = items[1]; v2 = items[2]; } static void Assign<T>(this IList<T> items, out T v0, out T v1, out T v2, out T v3) { v0 = items[0]; v1 = items[1]; v2 = items[2]; v3 = items[3]; } ... // And so on } 

This extension allows you to decompose the partition into separate variables, and not into a tuple:

 Assign(myString.Split('='), var out value, var out id); 
+1
source

You can create a tuple dynamically using reflection. This will give you a tuple for a variable number of elements.

Try a snapshot of the code,

  static void Main(string[] args) { var tupple = GetTuple<string>("hello=world".Split('=')); } public static object GetTuple<T>(params T[] values) { Type genericType = Type.GetType("System.Tuple`" + values.Length); Type[] typeArgs = values.Select(_ => typeof(T)).ToArray(); Type specificType = genericType.MakeGenericType(typeArgs); object[] constructorArguments = values.Cast<object>().ToArray(); return Activator.CreateInstance(specificType, constructorArguments); } 
0
source

Here is what I hope with you in the end:

 static void Main() { var a = new List<string> { "ID = Value", "id=value", "id = value" }; var values = new List<string>(); var ids = new List<string>(); for (int i = 0; i < a.Count; i++) { (string value, string id) = SplitText(a[i]); values.Add(value); ids.Add(id); } Console.WriteLine($"Values -> {string.Join(", ", values)}, ID -> {string.Join(", ", ids)}"); } private static (string, string) SplitText(string inputText) { var tokens = inputText.Split(new[] { ' ', '=' }, StringSplitOptions.RemoveEmptyEntries); return (tokens[0], tokens[1]); } 
0
source

Source: https://habr.com/ru/post/1275808/


All Articles