Convert IEnumerable<byte[]> to byte[] - c#

var r = from s in tempResult
select Encoding.GetEncoding("iso-8859-1").GetBytes(s);
I understand, this returns IEnumerable<byte[]>, but I looking for LINQ way to convert the whole IEnumerable<byte[]> to byte[].

None of the answers provided so far will work, because they will convert the IEnumerable<byte[]> to byte[][]. If your goal is to take all of the arrays in the enumerable and produce one big array, try this:
byte[] result = r.SelectMany(i => i).ToArray();
See this ideone example.
Note that this is not the most efficient way to do this. It would be faster to convert the original query result to a list, then compute the sum of the array lengths. Once that is done, you can allocate the final array immediately, then make one more pass over the result list and copy each result array's contents into the larger array.
The above LINQ query definitely makes this task easy, but it will not be fast. If this code becomes a bottleneck in the application, consider rewriting it this way.
I might as well provide an example of a more efficient implementation:
public static T[] JoinArrays<T>(this IEnumerable<T[]> self)
{
if (self == null)
throw new ArgumentNullException("self");
int count = 0;
foreach (var arr in self)
if (arr != null)
count += arr.Length;
var joined = new T[count];
int index = 0;
foreach (var arr in self)
if (arr != null)
{
Array.Copy(arr, 0, joined, index, arr.Length);
index += arr.Length;
}
return joined;
}
Note that whatever enumerable you pass in will be enumerated twice, so it would be a good idea to pass in a list or an array instead of a query, if that query is expensive.

Are you sure that's what you want to do? This code already returns a byte array:
Encoding.GetEncoding("iso-8859-1").GetBytes(s);
In any case, if you want to convert the enumeration to an array, you would do so like this:
var myArray = (from s in tempResult
select Encoding.GetEncoding("iso-8859-1").GetBytes(s)).ToArray();
EDIT
After your edit, I see I've misunderstood what you're trying to accomplish. If I understand correctly now, you're trying to get a byte array containing concatenated strings in tempResult? I would so it like this:
var concatenated = String.Join("", tempResult.ToArray());
var byteArray = Encoding.GetEncoding("iso-8859-1").GetBytes(concatenated);

What about ToArray extension method?
byte[] array = r.SelectMany(a => a).ToArray();

var r = (from s in tempResult
select Encoding.GetEncoding("iso-8859-1").GetBytes(s)
).ToArray();

Related

Change value of each element by linq

Is it possible to do sth like this in LINQ:
int[] d = new int[c.Length + 1];
int e = 1;
d.ToList().ForEach(r =>
{
r = e;
e++;
});
?.
When I did this, it returned me sequence of zeros.
Regards.
Yes, it would, for two reasons:
You're creating a copy of the original array as a List<int>, and then trying to modify the List<int>. That wouldn't modify the array.
Your lambda expression changes the value of the parameter, that's all. It doesn't modify the list.
Basically, LINQ is for querying. Don't even bother trying to do this: use a for loop if you want to modify the collection.
However, if your aim is to produce an array of 1...(c.Length+1), just use Enumerable.Range:
var array = Enumerable.Range(1, c.Length + 1).ToArray();

C# increase length of a string array [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
how to inset a new array to my jagged array
i have a problem, where i dont know how i can make a string array variable in array length.
i have this code now below:
string[] p = new string[10];
int num = 0;
foreach (Product products in GetAllProducts())
{
//do something
p[num]= "some variable result"
num++
}
The problem is, that i dont know how many of "p" i will get, although i know it atleast will be less than 10.
but if i put it on 0, i will get an error when i start it, because it doesn't know the "p[num]"
So i am looking for some way to make "p" have a variable length.
anyone could help me out a bit? thanx
============Solved==========
List<string> p = new List<string>();
int num = 0;
foreach (Product products in GetAllProducts())
{
string s= null;
//do something ( create s out of multiple parts += s etc.)
p.add(s)
num++
}
thanx to solution poster
Use an List<string> instead of an array, if you do not know the number of items you will need to add.
Your array length cannot be modified after it has been instantiated. Use ArrayList or Generic Lists.
var p = new new List<string>(10);
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}
What does GetAllProducts() return? Does it have a count or a length?! You should call that first, save it in a variable, get the count/length and then declare your array!
There's two solution.
If you want to keep using array :
int num = 0;
var list = GetAllProducts();
string[] p = new string[list.Length]; // Or list.Count if this is a collection
foreach (Product products in list)
{
//do something
p[num] = "some variable result";
num++;
}
Otherwise you should use a List like this :
List<string> p = new List<string>();
foreach (Product products in GetAllProducts())
{
//do something
p.Add("some variable result");
}
Use Array.Resize() method, which allows to resize it (by n number of indexes).
In my exmaple I will reize by 1 on each step of the way:
string[] array = new string[3]; //create array
for (int i = 0; i < 5; i++)
{
if (array.Length-1 < i) //checking for the available length
{
Array.Resize(ref array, array.Length + 1); //when to small, create a new index
}
array[i] = i.ToString(); //add an item to array[index] - of i
}
Because your code is using a foreach on the result from GetAllProducts, then GetAllProducts must be returning a IEnumerable collection. Probably the best solution would be to simply assign the result of GetAllProducts to such a collection. For example, perhaps it already returns a list of strings? So you can do:
List<string> strings = GetAllProducts();
There is no need to have a foreach loop to create an array when you already have a collection anyway being returned from GetAllProducts.
Or simply:
var strings = GetAllProducts();
to let the compiler work out the type of strings.
Most things you can do with an array you can also do with a List, and some more (such as adding items to the end of the List).
Perhaps you can post the signature of GetAllProducts (especially its return type) so we can better advise you?
I see many gave you the right answer which is the use of Lists. If you still need an array in the end, you can easily convert your list into an Array like this :
string[] tempArray = myList.ToArray();

Parse int[] from "1,2,3"

I have a multiselect dropdown called ID that submits ID=1,2,3 which I need parsed into an integer array to do a Contains() on in a filter method. At the moment I use:
string[] ids = Request["ID"].Split(',');
Which I don't really like because its slower to compare string than int. Any suggestions?
Request["ID"].Split(',').Select(x=>int.Parse(x)).ToArray();
Of course, this will throw if any of the resulting numeric strings are not "parseable" (does such a word exist?).
It depends on how many times you will look up in the array if converting to ints are faster or the string comparison is faster.
HashSet<int> ids = new HashSet<int>(from s in Request["ID"].Split(',')
select int.Parse(s));
But probably the fastest if you have many id:s will be to create a HashSet<string>:
HashSet<string> = new HashSet<string>(string[] ids = Request["ID"].Split(','));
int[] ids = Request["ID"].Split(',').Select(Convert.ToInt32).ToArray();
First:
string[] arr = Request["ID"].Split(',')
Then:
Array.ConvertAll(arr, s => Int32.Parse(s));
Array.ConvertAll(arr, Int32.Parse);
arr.Select(s => Int32.Parse(s));
arr.Select(Int32.Parse);
Then:
new HashSet<int>(result);
(the most fast container to perform Contains())
See also:
Convert string[] to int[] in one string of code using LINQ
Which one is faster in processing and conversion int.Parse(), int.TryParse(), Convert.Int32()
If you don't have linq, you can:
string[] ids = Request["ID"].Split(',');
int[] items = new int[ids.Length];
for(int i = 0; i<ids.Length; i++)
{
items[i] = int.Parse(ids[i]);
}

Shove a delimited string into a List<int>

If I have for example the following string:
"123;3344;4334;12"
and I want these numbers in a generic List<int>, I guess I don't know of a good way here other than to split in a loop and do a conversion then add to a List<int> through each iteration. Does anyone have other ways to go about this?
Updated. Here's what I came up with. I want to do this the old fashion way, not with LINQ because I'm trying to get better with just strings, arrays, lists and manipulating and converting in general.
public List<int> StringToList(string stringToSplit, char splitDelimiter)
{
List<int> list = new List<int>();
if (string.IsNullOrEmpty(stringToSplit))
return list;
string[] values = stringToSplit.Split(splitDelimiter);
if (values.Length <= 1)
return list;
foreach (string s in values)
{
int i;
if (Int32.TryParse(s, out i))
list.Add(i);
}
return list;
}
This is a new string utility method I plan on using whenever I need to convert a delimited string list to List
So I'm returning an empty list back to the caller if something fails. Good/Bad? is it pretty common to do this?
Yes, there are more "elegant" ways to do this with LINQ but I want to do it manually..the old way for now just for my own understanding.
Also, what bothers me about this:
list.AddRange(str.Split(';').Select(Int32.Parse));
is that I have no idea:
How to shove in a TryParse there instead.
What if the str.Split(';').Select(Int32.Parse) just fails for whatever reason...then the method that this AddRange resides in is going to blow up and unless I add a try/catch around this whole thing, I'm screwed if I don't handle it properly.
static int? ToInt32OrNull(string s)
{
int value;
return (Int32.TryParse(s, out value)) ? value : default(int?);
}
// ...
var str = "123;3344;4334;12";
var list = new List<int>();
list.AddRange(str.Split(';')
.Select(ToInt32OrNull)
.Where(i => i != null)
.Cast<int>());
Questioner notes:
I don't know of a good way here other than to split in a loop and do a conversion then add to a List
In general, this is a major reason why LINQ was brought into C# - to remove the need to work with sequences of values by implementing loops, and instead just declare your intention to transform the sequence. If you ever find yourself thinking "I don't know how to do this except with a loop" - it's time to look into a LINQ construct which will do the work for you.
Performance Update:
Performance of LINQ has been quesioned below. While in the comments the idea of LINQ being slower is defended since we gain the benefits of readability, maintainability and composibility, there is another aspect which gives LINQ an easy performance advantage: parallelism. Here is an example where adding just one extension method call, AsParallel() doubles the performance. This is a great example of where scale-out beats micro-optimization without even needing to measure very carefully. Note I'm not claiming that micro-optimizations are not ever needed, but with the tools we have available at this level of absraction, the need becomes vanishingly small.
class Program
{
private const int ElementCount = 10000000;
static void Main(string[] args)
{
var str = generateString();
var stopwatch = new Stopwatch();
var list1 = new List<int>(ElementCount);
var list2 = new List<int>(ElementCount);
var split = str.Split(';');
stopwatch.Start();
list1.AddRange(split
.Select(ToInt32OrNull)
.Where(i => i != null)
.Cast<int>());
stopwatch.Stop();
TimeSpan nonParallel = stopwatch.Elapsed;
stopwatch.Restart();
list2.AddRange(split
.AsParallel()
.Select(ToInt32OrNull)
.Where(i => i != null)
.Cast<int>());
stopwatch.Stop();
TimeSpan parallel = stopwatch.Elapsed;
Debug.WriteLine("Non-parallel: {0}", nonParallel);
Debug.WriteLine("Parallel: {0}", parallel);
}
private static String generateString()
{
var builder = new StringBuilder(1048576);
var rnd = new Random();
for (int i = 0; i < ElementCount; i++)
{
builder.Append(rnd.Next(99999));
builder.Append(';');
}
builder.Length--;
return builder.ToString();
}
static int? ToInt32OrNull(string s)
{
int value;
return (Int32.TryParse(s, out value)) ? value : default(int?);
}
}
Non-parallel: 00:00:07.0719911
Parallel: 00:00:04.5933906
string str = "123;3344;4334;12";
List<int> list = new List<int>();
foreach (string s in str.Split(';'))
{
list.Add( Int32.Parse(s));
}
List<int> list = (from numString in "123;3344;4334;12".Split(';')
select int.Parse(numString)).ToList();
string myString = "123;3344;4334;12";
var ints = new List<int>();
(from s in myString.Split(';')
select int.Parse()).ToList().ForEach(i=>ints.Add(i));
I've heard .Net 4.0 may have added ForEach to Enumerable<T>, so the ToList might be unnecessary there (can't test).
I think this is simplest
var str = "123;3344;4334;12";
var list = str.Split(';').ToList().Cast<int>();

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