String Parsing in C# - c#

What is the most efficient way to parse a C# string in the form of
"(params (abc 1.3)(sdc 2.0)(www 3.05)....)"
into a struct in the form
struct Params
{
double abc,sdc,www....;
}
Thanks
EDIT
The structure always have the same parameters (same names,only doubles, known at compile time).. but the order is not granted.. only one struct at a time..

using System;
namespace ConsoleApplication1
{
class Program
{
struct Params
{
public double abc, sdc;
};
static void Main(string[] args)
{
string s = "(params (abc 1.3)(sdc 2.0))";
Params p = new Params();
object pbox = (object)p; // structs must be boxed for SetValue() to work
string[] arr = s.Substring(8).Replace(")", "").Split(new char[] { ' ', '(', }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < arr.Length; i+=2)
typeof(Params).GetField(arr[i]).SetValue(pbox, double.Parse(arr[i + 1]));
p = (Params)pbox;
Console.WriteLine("p.abc={0} p.sdc={1}", p.abc, p.sdc);
}
}
}
Note: if you used a class instead of a struct the boxing/unboxing would not be necessary.

Depending on your complete grammar you have a few options:
if it's a very simple grammar and you don't have to test for errors in it you could simply go with the below (which will be fast)
var input = "(params (abc 1.3)(sdc 2.0)(www 3.05)....)";
var tokens = input.Split('(');
var typeName = tokens[0];
//you'll need more than the type name (assembly/namespace) so I'll leave that to you
Type t = getStructFromType(typeName);
var obj = TypeDescriptor.CreateInstance(null, t, null, null);
for(var i = 1;i<tokens.Length;i++)
{
var innerTokens = tokens[i].Trim(' ', ')').Split(' ');
var fieldName = innerTokens[0];
var value = Convert.ToDouble(innerTokens[1]);
var field = t.GetField(fieldName);
field.SetValue(obj, value);
}
that simple approach however requires a well conforming string or it will misbehave.
If the grammar is a bit more complicated e.g. nested ( ) then that simple approach won't work.
you could try to use a regEx but that still requires a rather simple grammar so if you end up having a complex grammar your best choice is a real parser. Irony is easy to use since you can write it all in simple c# (some knowledge of BNF is a plus though).

Do you need to support multiple structs ? In other words, does this need to be dynamic; or do you know the struct definition at compile time ?
Parsing the string with a regex would be the obvious choice.
Here is a regex, that will parse your string format:
private static readonly Regex regParser = new Regex(#"^\(params\s(\((?<name>[a-zA-Z]+)\s(?<value>[\d\.]+)\))+\)$", RegexOptions.Compiled);
Running that regex on a string will give you two groups named "name" and "value". The Captures property of each group will contain the names and values.
If the struct type is unknown at compile time, then you will need to use reflection to fill in the fields.
If you mean to generate the struct definition at runtime, you will need to use Reflection to emit the type; or you will need to generate the source code.
Which part are you having trouble with ?

A regex can do the job for you:
public Dictionary<string, double> ParseString(string input){
var dict = new Dictionary<string, double>();
try
{
var re = new Regex(#"(?:\(params\s)?(?:\((?<n>[^\s]+)\s(?<v>[^\)]+)\))");
foreach (Match m in re.Matches(input))
dict.Add(m.Groups["n"].Value, double.Parse(m.Groups["v"].Value));
}
catch
{
throw new Exception("Invalid format!");
}
return dict;
}
use it like:
string str = "(params (abc 1.3)(sdc 2.0)(www 3.05))";
var parsed = ParseString(str);
// parsed["abc"] would now return 1.3
That might fit better than creating a lot of different structs for every possible input string, and using reflection for filling them. I dont think that is worth the effort.
Furthermore I assumed the input string is always in exactly the format you posted.

You might consider performing just enough string manipulation to make the input look like standard command line arguments then use an off-the-shelf command line argument parser like NDesk.Options to populate the Params object. You give up some efficiency but you make it up in maintainability.
public Params Parse(string input)
{
var #params = new Params();
var argv = ConvertToArgv(input);
new NDesk.Options.OptionSet
{
{"abc=", v => Double.TryParse(v, out #params.abc)},
{"sdc=", v => Double.TryParse(v, out #params.sdc)},
{"www=", v => Double.TryParse(v, out #params.www)}
}
.Parse(argv);
return #params;
}
private string[] ConvertToArgv(string input)
{
return input
.Replace('(', '-')
.Split(new[] {')', ' '});
}

Do you want to build a data representation of your defined syntax?
If you are looking for easily maintainability, without having to write long RegEx statements you could build your own Lexer parser. here is a prior discussion on SO with good links in the answers as well to help you
Poor man's "lexer" for C#

I would just do a basic recursive-descent parser. It may be more general than you want, but nothing else will be much faster.

Here's an out-of-the-box approach:
convert () to {} and [SPACE] to ":", then use System.Web.Script.Serialization.JavaScriptSerializer.Deserialize
string s = "(params (abc 1.3)(sdc 2.0))"
.Replace(" ", ":")
.Replace("(", "{")
.Replace(")","}");
return new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize(s);

Related

How to get value of escape characters in c#?

I want to know the ASCII value of an escape sequence in runtime. for example:
string x = "\\b";
char res = someFunctionCall(x);
//res = '\b' = 0x08
The difference here that I only know x at runtime.
I know that this can be made with simple switch (already doing that), but I was wondering if it can be made using some existing c# call. I tried Char.Parse(x), but it didn't work.
Edit: I'm not talking here about converting '\b' to its corresponding ASCII value, rather, I'd like to parse "\\b" as what you write in c# to get '\b'.
There is slow but rather easy way to do this. compile your code at runtime and let c# compiler take care of that! I know its overkill for what you want. but it works.
Anyway as #JonSkeet noted you can use a dictionary for simple escape sequences. take your list from here https://msdn.microsoft.com/en-us/library/h21280bw.aspx
Here is solution by compiling code at runtime, Note that its VERY SLOW, so I suggest you to replace and map multiple characters at once so compiler only runs and evaluate all of that for you only once.
using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
//...
private static void Main()
{
string x = "\\b";
string res = Evaluate(x);
Console.WriteLine(res);
}
public static string Evaluate(string input)
{
// code to compile.
const string format = "namespace EscapeSequenceMapper {{public class Program{{public static string Main(){{ return \"{0}\";}}}}}}";
// compile code.
var cr = new CSharpCodeProvider().CompileAssemblyFromSource(
new CompilerParameters { GenerateInMemory = true }, string.Format(format, input));
if (cr.Errors.HasErrors) return null;
// get main method and invoke.
var method = cr.CompiledAssembly.GetType("EscapeSequenceMapper.Program").GetMethod("Main");
return (string)method.Invoke(null, null);
}

Custom List<string[]> Sort

I have a list of string[].
List<string[]> cardDataBase;
I need to sort that list by each list-item's second string value (item[1]) in custom order.
The custom order is a bit complicated, order by those starting characters:
"MW1"
"FW"
"DN"
"MWSTX1CK"
"MWSTX2FF"
then order by these letters following above starting letters:
"A"
"Q"
"J"
"C"
"E"
"I"
"A"
and then by the numbers following above.
a sample, unordered list left, ordered right:
MW1E10 MW1Q04
MWSTX2FFI06 MW1Q05
FWQ02 MW1E10
MW1Q04 MW1I06
MW1Q05 FWQ02
FWI01 FWI01
MWSTX2FFA01 DNC03
DNC03 MWSTX1CKC02
MWSTX1CKC02 MWSTX2FFI03
MWSTX2FFI03 MWSTX2FFI06
MW1I06 MWSTX2FFA01
I tried Linq but I am not that good in it right now and cannot solve this on my own. Do I need a dictionary, regex or a dictionary with regex in it? What would be the best approach?
I think you're approaching this incorrectly. You're not sorting strings, you're sorting structured objects that are misrepresented as strings (somebody aptly named this antipattern "stringly typed"). Your requirements show that you know this structure, yet it's not represented in the datastructure List<string[]>, and that's making your life hard. You should parse that structure into a real type (struct or class), and then sort that.
enum PrefixCode { MW1, FW, DN, MWSTX1CK, MWSTX2FF, }
enum TheseLetters { Q, J, C, E, I, A, }
struct CardRecord : IComparable<CardRecord> {
public readonly PrefixCode Code;
public readonly TheseLetters Letter;
public readonly uint Number;
public CardRecord(string input) {
Code = ParseEnum<PrefixCode>(ref input);
Letter = ParseEnum<TheseLetters>(ref input);
Number = uint.Parse(input);
}
static T ParseEnum<T>(ref string input) { //assumes non-overlapping prefixes
foreach(T val in Enum.GetValues(typeof(T))) {
if(input.StartsWith(val.ToString())) {
input = input.Substring(val.ToString().Length);
return val;
}
}
throw new InvalidOperationException("Failed to parse: "+input);
}
public int CompareTo(CardRecord other) {
var codeCmp = Code.CompareTo(other.Code);
if (codeCmp!=0) return codeCmp;
var letterCmp = Letter.CompareTo(other.Letter);
if (letterCmp!=0) return letterCmp;
return Number.CompareTo(other.Number);
}
public override string ToString() {
return Code.ToString() + Letter + Number.ToString("00");
}
}
A program using the above to process your example might then be:
static class Program {
static void Main() {
var inputStrings = new []{ "MW1E10", "MWSTX2FFI06", "FWQ02", "MW1Q04", "MW1Q05",
"FWI01", "MWSTX2FFA01", "DNC03", "MWSTX1CKC02", "MWSTX2FFI03", "MW1I06" };
var outputStrings = inputStrings
.Select(s => new CardRecord(s))
.OrderBy(c => c)
.Select(c => c.ToString());
Console.WriteLine(string.Join("\n", outputStrings));
}
}
This generates the same ordering as in your example. In real code, I'd recommend you name the types according to what they represent, and not, for example, TheseLetters.
This solution - with a real parse step - is superior because it's almost certain that you'll want to do more with this data at some point, and this allows you to actually access the components of the data easily. Furthermore, it's comprehensible to a future maintainer since the reason behind the ordering is somewhat clear. By contrast, if you chose to do complex string-based processing it's often very hard to understand what's going on (especially if it's part of a larger program, and not a tiny example as here).
Making new types is cheap. If your method's return value doesn't quite "fit" in an existing type, just make a new one, even if that means 1000's of types.
A bit spoonfeeding, but I found this question pretty interesting and perhaps it will be useful for others, also added some comments to explain:
void Main()
{
var cardDatabase = new List<string>{
"MW1E10",
"MWSTX2FFI06",
"FWQ02",
"MW1Q04",
"MW1Q05",
"FWI01",
"MWSTX2FFA01",
"DNC03",
"MWSTX1CKC02",
"MWSTX2FFI03",
"MW1I06",
};
var orderTable = new List<string>[]{
new List<string>
{
"MW1",
"FW",
"DN",
"MWSTX1CK",
"MWSTX2FF"
},
new List<string>
{
"Q",
"J",
"C",
"E",
"I",
"A"
}
};
var test = cardDatabase.Select(input => {
var r = Regex.Match(input, "^(MW1|FW|DN|MWSTX1CK|MWSTX2FF)(A|Q|J|C|E|I|A)([0-9]+)$");
if(!r.Success) throw new Exception("Invalid data!");
// for each input string,
// we are going to split it into "substrings",
// eg: MWSTX1CKC02 will be
// [MWSTX1CK, C, 02]
// after that, we use IndexOf on each component
// to calculate "real" order,
// note that thirdComponent(aka number component)
// does not need IndexOf because it is already representing the real order,
// we still want to convert string to integer though, because we don't like
// "string ordering" for numbers.
return new
{
input = input,
firstComponent = orderTable[0].IndexOf(r.Groups[1].Value),
secondComponent = orderTable[1].IndexOf(r.Groups[2].Value),
thirdComponent = int.Parse(r.Groups[3].Value)
};
// and after it's done,
// we start using LINQ OrderBy and ThenBy functions
// to have our custom sorting.
})
.OrderBy(calculatedInput => calculatedInput.firstComponent)
.ThenBy(calculatedInput => calculatedInput.secondComponent)
.ThenBy(calculatedInput => calculatedInput.thirdComponent)
.Select(calculatedInput => calculatedInput.input)
.ToList();
Console.WriteLine(test);
}
You can use the Array.Sort() method. Where your first parameter is the string[] you're sorting and the second parameter contains the complicated logic of determining the order.
You can use the IEnumerable.OrderBy method provided by the System.Linq namespace.

How to convert string to decimal[] in C#

Is there a way to achieve this?
I tried:
string str = "{34.10,0,0.00}"; //the string as I get it from Postgres DB
decimal[] won;
won = (decimal[])(str); //Cannot convert type 'string' to 'decimal[]'
What I would ideally want is to get into won:
won[0] = 34.10
won[1] = 0
won[2] = 0.00
Surely, I can go and split by commas, and put it in the array but I'm wondering if there's a better way.
You have to Split
won = str.Trim('{', '}').Split(',').Select(decimal.Parse).ToArray();
Edit: This part is just for fun
There is no way to cast string to a decimal[] array directly, but if you want you can add a decimal wrapper class and define implicit conversions:
class MyDecimal
{
private decimal[] _values;
public MyDecimal(int size)
{
_values = new decimal[size];
}
public decimal this[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
public static implicit operator MyDecimal(string str)
{
var numbers = str.Trim('{', '}').Split(',');
MyDecimal d = new MyDecimal(numbers.Length);
d._values = numbers
.Select(x => decimal.Parse(x,CultureInfo.InvariantCulture))
.ToArray();
return d;
}
public static implicit operator string(MyDecimal md)
{
return string.Join(",", md._values);
}
}
Then you can do:
string str = "{34.10,0,0.00}"; //the string as I get it from Postgres DB
MyDecimal won = str;
I first misread your question. The real answer is: I know of no other way than splitting and converting in loops or using LINQ (for a LINQ sample see Selman22's answer). There's no way to cast a string to an array in one go.
While it is essentially what you suggest, you could try this:
// Remove leading and trailing brackets
string s = str.Trim('{', '}');
// Split numbers
string[] parts = s.Split(',');
decimal[] nums = new decimal[parts.Length];
// Convert
for (int i = 0; i < parts.Length; i++)
nums[i] = Convert.ToDecimal(parts[i]);
Just to play devil's advocate to those who say you have no option but to split:
var result = new JavaScriptSerializer()
.Deserialize<decimal[]>(str.Replace('{', '[').Replace('}', ']'))
here is another but probably not a better way in regex
string str = "{34.10,0,0.00}";
string pattern = #"([\d]+[\.]|[\d]?)[\d]+";
decimal[] result = Regex.Matches(str, pattern, RegexOptions.None)
.Cast<Match>()
.Select(x => decimal.Parse(x.Value))
.ToArray();
but remember Jamie Zawinski:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
Another way would be using a StringReader and managing the split
There is no better way. At least until C# is backed up by an AI which will just guess what you are trying to do by casting one datatype into another by a custom logic.
Any programmer would guess what you want. Until now though the C# compiler is no wizard.

Using an array in String.Format

Currently I'm working on an web-API dependent application. I have made a class with a lot of API strings like: /api/lol/static-data/{region}/v1/champion/{id}. Also I made a method:
public static String request(String type, Object[] param)
{
return "";
}
This is going to do the requesting stuff. Because it's very different with each request type how many parameters are being used, I'm using an array for this. Now the question is, is it posssible to String.Format using an array for the paramaters while the keys in the strings are not numbers? Or does anyone know how to do this in a different way?
No, string.Format only supports index-based parameter specifications.
This:
"/api/lol/static-data/{region}/v1/champion/{id}"
^^^^^^^^ ^^^^
will have to be handled using a different method, like string.Replace or a Regex.
You will need to:
Decide on the appropriate method for doing the replacements
Decide how an array with index-based values should map to the parameters, are they positional? ie. {region} is the first element of the array, {id} is the second, etc.?
Here is a simple LINQPad program that demonstrates how I would do it (though I would add a bit more error handling, maybe caching of the reflection info if this is executed a lot, some unit-tests, etc.):
void Main()
{
string input = "/api/lol/static-data/{region}/v1/champion/{id}";
string output = ReplaceArguments(input, new
{
region = "Europe",
id = 42
});
output.Dump();
}
public static string ReplaceArguments(string input, object arguments)
{
if (arguments == null || input == null)
return input;
var argumentsType = arguments.GetType();
var re = new Regex(#"\{(?<name>[^}]+)\}");
return re.Replace(input, match =>
{
var pi = argumentsType.GetProperty(match.Groups["name"].Value);
if (pi == null)
return match.Value;
return (pi.GetValue(arguments) ?? string.Empty).ToString();
});
}

int array to string

In C#, I have an array of ints, containing digits only. I want to convert this array to string.
Array example:
int[] arr = {0,1,2,3,0,1};
How can I convert this to a string formatted as: "012301"?
at.net 3.5 use:
String.Join("", new List<int>(array).ConvertAll(i => i.ToString()).ToArray());
at.net 4.0 or above use: (see #Jan Remunda's answer)
string result = string.Join("", array);
You can simply use String.Join function, and as separator use string.Empty because it uses StringBuilder internally.
string result = string.Join(string.Empty, new []{0,1,2,3,0,1});
E.g.: If you use semicolon as separator, the result would be 0;1;2;3;0;1.
It actually works with null separator, and second parameter can be enumerable of any objects, like:
string result = string.Join(null, new object[]{0,1,2,3,0,"A",DateTime.Now});
I realize my opinion is probably not the popular one, but I guess I have a hard time jumping on the Linq-y band wagon. It's nifty. It's condensed. I get that and I'm not opposed to using it where it's appropriate. Maybe it's just me, but I feel like people have stopped thinking about creating utility functions to accomplish what they want and instead prefer to litter their code with (sometimes) excessively long lines of Linq code for the sake of creating a dense 1-liner.
I'm not saying that any of the Linq answers that people have provided here are bad, but I guess I feel like there is the potential that these single lines of code can start to grow longer and more obscure as you need to handle various situations. What if your array is null? What if you want a delimited string instead of just purely concatenated? What if some of the integers in your array are double-digit and you want to pad each value with leading zeros so that the string for each element is the same length as the rest?
Taking one of the provided answers as an example:
result = arr.Aggregate(string.Empty, (s, i) => s + i.ToString());
If I need to worry about the array being null, now it becomes this:
result = (arr == null) ? null : arr.Aggregate(string.Empty, (s, i) => s + i.ToString());
If I want a comma-delimited string, now it becomes this:
result = (arr == null) ? null : arr.Skip(1).Aggregate(arr[0].ToString(), (s, i) => s + "," + i.ToString());
This is still not too bad, but I think it's not obvious at a glance what this line of code is doing.
Of course, there's nothing stopping you from throwing this line of code into your own utility function so that you don't have that long mess mixed in with your application logic, especially if you're doing it in multiple places:
public static string ToStringLinqy<T>(this T[] array, string delimiter)
{
// edit: let's replace this with a "better" version using a StringBuilder
//return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(array[0].ToString(), (s, i) => s + "," + i.ToString());
return (array == null) ? null : (array.Length == 0) ? string.Empty : array.Skip(1).Aggregate(new StringBuilder(array[0].ToString()), (s, i) => s.Append(delimiter).Append(i), s => s.ToString());
}
But if you're going to put it into a utility function anyway, do you really need it to be condensed down into a 1-liner? In that case why not throw in a few extra lines for clarity and take advantage of a StringBuilder so that you're not doing repeated concatenation operations:
public static string ToStringNonLinqy<T>(this T[] array, string delimiter)
{
if (array != null)
{
// edit: replaced my previous implementation to use StringBuilder
if (array.Length > 0)
{
StringBuilder builder = new StringBuilder();
builder.Append(array[0]);
for (int i = 1; i < array.Length; i++)
{
builder.Append(delimiter);
builder.Append(array[i]);
}
return builder.ToString()
}
else
{
return string.Empty;
}
}
else
{
return null;
}
}
And if you're really so concerned about performance, you could even turn it into a hybrid function that decides whether to do string.Join or to use a StringBuilder depending on how many elements are in the array (this is a micro-optimization, not worth doing in my opinion and possibly more harmful than beneficial, but I'm using it as an example for this problem):
public static string ToString<T>(this T[] array, string delimiter)
{
if (array != null)
{
// determine if the length of the array is greater than the performance threshold for using a stringbuilder
// 10 is just an arbitrary threshold value I've chosen
if (array.Length < 10)
{
// assumption is that for arrays of less than 10 elements
// this code would be more efficient than a StringBuilder.
// Note: this is a crazy/pointless micro-optimization. Don't do this.
string[] values = new string[array.Length];
for (int i = 0; i < values.Length; i++)
values[i] = array[i].ToString();
return string.Join(delimiter, values);
}
else
{
// for arrays of length 10 or longer, use a StringBuilder
StringBuilder sb = new StringBuilder();
sb.Append(array[0]);
for (int i = 1; i < array.Length; i++)
{
sb.Append(delimiter);
sb.Append(array[i]);
}
return sb.ToString();
}
}
else
{
return null;
}
}
For this example, the performance impact is probably not worth caring about, but the point is that if you are in a situation where you actually do need to be concerned with the performance of your operations, whatever they are, then it will most likely be easier and more readable to handle that within a utility function than using a complex Linq expression.
That utility function still looks kind of clunky. Now let's ditch the hybrid stuff and do this:
// convert an enumeration of one type into an enumeration of another type
public static IEnumerable<TOut> Convert<TIn, TOut>(this IEnumerable<TIn> input, Func<TIn, TOut> conversion)
{
foreach (TIn value in input)
{
yield return conversion(value);
}
}
// concatenate the strings in an enumeration separated by the specified delimiter
public static string Delimit<T>(this IEnumerable<T> input, string delimiter)
{
IEnumerator<T> enumerator = input.GetEnumerator();
if (enumerator.MoveNext())
{
StringBuilder builder = new StringBuilder();
// start off with the first element
builder.Append(enumerator.Current);
// append the remaining elements separated by the delimiter
while (enumerator.MoveNext())
{
builder.Append(delimiter);
builder.Append(enumerator.Current);
}
return builder.ToString();
}
else
{
return string.Empty;
}
}
// concatenate all elements
public static string ToString<T>(this IEnumerable<T> input)
{
return ToString(input, string.Empty);
}
// concatenate all elements separated by a delimiter
public static string ToString<T>(this IEnumerable<T> input, string delimiter)
{
return input.Delimit(delimiter);
}
// concatenate all elements, each one left-padded to a minimum length
public static string ToString<T>(this IEnumerable<T> input, int minLength, char paddingChar)
{
return input.Convert(i => i.ToString().PadLeft(minLength, paddingChar)).Delimit(string.Empty);
}
Now we have separate and fairly compact utility functions, each of which are arguable useful on their own.
Ultimately, my point is not that you shouldn't use Linq, but rather just to say don't forget about the benefits of creating your own utility functions, even if they are small and perhaps only contain a single line that returns the result from a line of Linq code. If nothing else, you'll be able to keep your application code even more condensed than you could achieve with a line of Linq code, and if you are using it in multiple places, then using a utility function makes it easier to adjust your output in case you need to change it later.
For this problem, I'd rather just write something like this in my application code:
int[] arr = { 0, 1, 2, 3, 0, 1 };
// 012301
result = arr.ToString<int>();
// comma-separated values
// 0,1,2,3,0,1
result = arr.ToString(",");
// left-padded to 2 digits
// 000102030001
result = arr.ToString(2, '0');
To avoid the creation of an extra array you could do the following.
var builder = new StringBuilder();
Array.ForEach(arr, x => builder.Append(x));
var res = builder.ToString();
string result = arr.Aggregate("", (s, i) => s + i.ToString());
(Disclaimer: If you have a lot of digits (hundreds, at least) and you care about performance, I suggest eschewing this method and using a StringBuilder, as in JaredPar's answer.)
You can do:
int[] arr = {0,1,2,3,0,1};
string results = string.Join("",arr.Select(i => i.ToString()).ToArray());
That gives you your results.
I like using StringBuilder with Aggregate(). The "trick" is that Append() returns the StringBuilder instance itself:
var sb = arr.Aggregate( new StringBuilder(), ( s, i ) => s.Append( i ) );
var result = sb.ToString();
string.Join("", (from i in arr select i.ToString()).ToArray())
In the .NET 4.0 the string.Join can use an IEnumerable<string> directly:
string.Join("", from i in arr select i.ToString())
I've left this here for posterity but don't recommend its use as it's not terribly readable. This is especially true now that I've come back to see if after a period of some time and have wondered what I was thinking when I wrote it (I was probably thinking 'crap, must get this written before someone else posts an answer'.)
string s = string.Concat(arr.Cast<object>().ToArray());
The most efficient way is not to convert each int into a string, but rather create one string out of an array of chars. Then the garbage collector only has one new temp object to worry about.
int[] arr = {0,1,2,3,0,1};
string result = new string(Array.ConvertAll<int,char>(arr, x => Convert.ToChar(x + '0')));
This is a roundabout way to go about it its not much code and easy for beginners to understand
int[] arr = {0,1,2,3,0,1};
string joined = "";
foreach(int i in arr){
joined += i.ToString();
}
int number = int.Parse(joined);
If this is long array you could use
var sb = arr.Aggregate(new StringBuilder(), ( s, i ) => s.Append( i ), s.ToString());
// This is the original array
int[] nums = {1, 2, 3};
// This is an empty string we will end up with
string numbers = "";
// iterate on every char in the array
foreach (var item in nums)
{
// add the char to the empty string
numbers += Convert.ToString(item);
}
// Write the string in the console
Console.WriteLine(numbers);

Categories

Resources