I need an easy way to convert a List<int> to a string array.
I have:
var the_list = new List<int>();
the_list.Add(1);
the_list.Add(2);
the_list.Add(3);
string[] the_array = new string[the_list.Count];
for(var i = 0 ; i < the_array.Count; ++i)
the_array[i] = the_list[i].ToString();
...which looks to be very ugly to me.
Is there an easier way?
Note: I'm looking for an easier way - not necessarily a faster way.
Use LINQ:
string[] the_array = the_list.Select(i => i.ToString()).ToArray();
I know you have a good answer, but you don't need LINQ or Select. You can do it with a ConvertAll and an anonymous method. Like this:
var list = new List<int>();
....
var array = list.ConvertAll( x => x.ToString() ).ToArray();
Similar idea, but I think this is not linq. in case that matters.
Sorry, I don't have .NET installed on this machine, so totally untested:
var theList = new List<int>() { 1, 2, 3 };
var theArray = theList.Select(e => e.ToString()).ToArray(); // Lambda Form
var theArray = (from e in theList select e.ToString()).ToArray(); // Query Form
List has a ToArray() method. It will save you typing but probably won't be more efficient.
Because your list only has a number, you can easily convert them to a string. Just create a loop and convert its members to the string.
string[] the_array = new string[the_list.Count];
int i=0;
foreach(var item in the_list)
{
the_array[i] = item.ToString();
i++;
}
Related
I am new to C# language, I have started learning LINQ in that
So I just want to convert the code using linq. Is there any way to do. The current implementation is not a stylish one.
var list = new List<int>();
for (int index = 0; index < contentList.Count; index++)
{
list.Add(MyClass.GetCorrespondence(module, index));
}
return list;
You could write it like this:
var list = contentList.Select((_, i) => MyClass.GetCorrespondence(module, i)).ToList();
or like this
var list = Enumerable.Range(0,contentList.Count).Select(i => MyClass.GetCorrespondence(module, i)).ToList();
But, honestly, dont do either! Your code is perfectly readable as it is.
If you must use LINQ for this then you can use the overload for Select which "projects each element of a sequence into a new form by incorporating the element's index." e.g:
list.AddRange(contentList.Select((c, index) => MyClass.GetCorrespondence(c, index));
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netframework-4.8
this method work:
var result= contentList.Select((paramter,index)=>MyClass.GetCorrespondence(module,index)).ToList();
If you're desperate to do it with Linq then you could try:
list.AddRange(Enumerable.Range(0, contentList.Count).Select(index => MyClass.GetCorrespondence(module, index)))
or:
list = Enumerable.Range(0, contentList.Count).Select(index => MyClass.GetCorrespondence(module, index)).ToList();
You could also use the ForEach LINQ statement.
contentList.ForEach(x => list.Add(MyClass.GetCorrespondence(module, x)));
EDIT: Any reason why this was down voted?
Basically I have a list containing all items. Then I have a string containing the IDs I want to grab out from the list, to do this I split the string into an Int array and later use this and LINQ to get the items I want from the list
Like this :
List<T> lstAllList = Model.getAllItems();
string stringIDs = "8,9,12,11,7";
int[] intArray = stringIDs.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
List<T> lstLimitedList = (from r in lstAllList where intArray.Contains(r.id) select r).ToList();
Which works great.
But the issue here is that I want to have my list ordered in the same way as the string of IDs is, i.e 8,9,12,11,7 like in this example.
But the returned list from the LINQ sorts it by the id by default, so the returned list is 7,8,9,11,12.
Is there a way to prevent it from sorting it like this or is there a way to sort the new list with my int array?
Sure, just sort by the index of the ID in the array:
string stringIDs = "8,9,12,11,7";
int[] intArray = stringIDs.Split(',').Select(n => Convert.ToInt32(n)).ToArray();
var lstLimitedList = (
from r in lstAllList
where intArray.Contains(r.id)
orderby Array.IndexOf(intArray, r.id) // <--------
select r).ToList();
Simply getting the elements one at a time may be faster than trying to resort. (Anyone willing to calculate the O() costs?)
List<T> lstLimitedList = new List<T>();
foreach(int id in intArray)
{
lstLimitedList.Add(lstAllList.Where(item => item.id = id));
}
You could also use intArray.ForEach() if you're a LINQ maniac, but this is much easier to read. ;)
Try to rotate your query. Under word rotate I mean start with intArray and use join. Something like this:
List<T> lstLimitedList = (
from id in intArray
join item in lstAllList on id equals item.Id
select item).ToList();
Id use the intersect extension method with provided by LINQ!
int[] array ={ 8,9,12,11,7} // or your result from your split on string;
List<int> array2 = new List<int> { 8,9,12,11,7 } // your model.GetAllItems;
// Call Intersect extension method.
var intersect = array.Intersect(array2);
// Write intersection to screen.
foreach (int value in intersect)
{
Console.WriteLine(value); // Output: 8,9,12,11,7
}
Bit cleaner for me
Stop overusing LINQ guys. In this case linq is a total overkill. A much simpler and better performance-wise solution is the following:
string a = "8,9,12,11,7";
List<int> list = new List<int>();
string[] splitted = a.Split(',');
for (int i = 0; i < splitted.Length; i++)
{
list.Add(int.Parse(splitted[i]));
}
Which a single loop and without sorting etc.
I have a linq list obtained from database in my Model. Now I have a string array obtained from my controller. I want to construct a statement
pseudo-code
List<object> objlist = db.objects.tolist();
string[] strarray; // obtained from a long code.
var k = objlist.Where(u => u.somecol == strarray[0] || u.somecol == strarray[1]........strarray[n]).toList();
I am little bit confused how to accomplish this since my strarray[] is variable length and can contain upto 1000 words.
You can check if an array contains some item using the Array.IndexOf<T> Method:
bool strarrayContainsX = Array.IndexOf<string>(strarray, "X") >= 0;
However, I'd recommend you use a HashSet<string> instead of a string array for anything more than a few items. The HashSet<T> Class provides a Contains Method to check if a set contains some item:
HashSet<string> strset = new HashSet<string>(strarray);
bool strsetContainsX = strset.Contains("X");
The resulting query then looks like this:
var k = objlist.Where(u => strset.Contains(u.somecol)).ToList();
Use Contains:
var k = objlist.Where(u => strarray.Contains(u.somecol)).toList();
Try this:
List<object> objlist = db.objects.tolist();
string[] strarray; // obtained from a long code.
var k = objlist.Where(u => strarray.Contains(u.somecol)).toList();
var k = objlist.Where(u => strarray.Any(x=>x == u.somecol)).ToList();
I'm borrowing code from this question as I went there for inspiration. I have a list of objects, the object has an integer property and I want to foreach the list and the loop the number of integers.
It's a very basic for inside a foreach but I suspect I could use a SelectMany but can't get it working. The following code works but I would like a linq version.
//set up some data for our example
var tuple1 = new { Name = "Tuple1", Count = 2 };
var tuple2 = new { Name = "Tuple2", Count = 3 };
//put the tuples into a collection
var tuples = new [] { tuple1, tuple2 };
foreach(var item in tuples)
{
for(int i = 0; i < item.Count; i++)
Console.WriteLine(item.Name);
}
var flattened = tuples.SelectMany(t => Enumerable.Repeat(t.Name, t.Count));
foreach(var word in flattened)
{
Console.WriteLine(word);
}
You can use SelectMany; you simply need to generate sequences:
tuples.SelectMany(t => Enumerable.Repeat(t.Name, t.Count))
There is no Values property in your anonymous type. But i assume that you mean the Count property instead and you want to repeat the name this number. You can either use Enumerable.Range or Enumerable.Repeat:
IEnumerable<String> tupleNames = tuples
.Select(t => string.Join(Environment.NewLine, Enumerable.Repeat(t.Name, t.Count)));
Console.Write(string.Join(Environment.NewLine, tupleNames));
Output:
Tuple1
Tuple1
Tuple2
Tuple2
Tuple2
There is no linq equivalent of a foreach. You should use an actual foreach to iterate an IEnumerable and perform an action on each item.
I have a DB table that contains a comma separated list of ID's (ints) that are stored as nvarchar.
I have a get method to return these in one hit as a list. At the moment I think I'll have to do something like this:
List<int> ids = new List<int>();
string[] pageids = experssion.Split(separators)
foreach (string number in pageids)
{
ids.Add(Convert.ToInt32(number));
}
Can anyone think of a nicer way to do this ? Can I do it all on the split somehow ?
I'd to it like this:
var ids = expression.Split(separator).Select(s => int.Parse(s));
It uses the Linq extensions of .NET 3.0. As an alternative (saves one lambda), you could also do this which is arguably less readable:
var ids = expression.Split(separator).Select((Func<string, int>)int.Parse);
If you're not using C# 3.0, or aren't a fan of LINQ, you could do it the C# 2.0 way:
// This gives you an int[]
int[] pageids = Array.ConvertAll(expression.Split(separator), new Converter<string,int>(StringToInt));
// Add each id to the list
ids.AddRange(pageids);
public static int StringToInt(string s)
{
return int.Parse(s);
}
EDIT:
Or, even simpler as per Konrad's suggestion:
int[] pageids = Array.ConvertAll<string,int>(expression.Split(separator),int.Parse);
ids.AddRange(pageids);
With LINQ you can do this:
List<int> ids
= expression
.Split(separators)
.Select(number => Convert.ToInt32(number))
.ToList()