I have FileInfo[] fileInfos
I want to populate
string[] filesNames and List<string> fileNamesList using LINQ expression, how should I do it?
FileInfo has a Name property, so
var fileNamesList = fileInfos.Select(fi => fi.Name).ToList();
var filesNames = fileInfos.Select(fi => fi.Name).ToArray();
I don't see why you would need both a List and an array though.
var list = fileInfos.Select(fi => fi.Name).ToList();
var arr = fileInfos.Select(fi => fi.Name).ToArray();
List<string> filesNamesList = fileInfos.Select(fi => fi.Name).ToList();
string[] filesNames = filesNamesList.ToArray();
Try this code:
var fileList = fileInfos.Select(f => f.Name).ToList();
Related
I'm working with c#, and I have working code where I repeated same code every line, and that's because I'm creating list, conversions , extracting data etc.
So I have multiple foreach clauses,multiple lists, multiple conversions of list to datatables. My question is, what can I do to re-factorize this in order to have clean code?
Code:
private void BtnLoadReport_Click(object sender, EventArgs e)
{
var db = new SQLDataMgr();
List<string> DesignStatusList = new List<string>();
List<string> ShopStatusList = new List<string>();
List<string> CustomerTypeList = new List<string>();
List<string> CustomerList = new List<string>();
List<string> ResellerList = new List<string>();
List<string> StateList = new List<string>();
List<string> ProjectManagerList = new List<string>();
List<string> SalesRepresentativeList = new List<string>();
var checkedDesignStatus = cboDesignStatus.CheckBoxItems.Where(x => x.Checked);
var checkedShopStatus = cboShopStatus.CheckBoxItems.Where(x => x.Checked);
var checkedCustomerType = cboShopStatus.CheckBoxItems.Where(x => x.Check
var checkedCustomer = cboShopStatus.CheckBoxItems.Where(x => x.Checked);
var checkedReseller = cboShopStatus.CheckBoxItems.Where(x => x.Checked);
var checkedState = cboShopStatus.CheckBoxItems.Where(x => x.Checked);
var checkedProjectManager = cboShopStatus.CheckBoxItems.Where(x => x.Checked);
var checkedSalesRepresentative = cboShopStatus.CheckBoxItems.Where(x => x.Checked);
foreach (var i in checkedDesignStatus)
{
DesignStatusList.Add(i.Text);
}
foreach (var i in checkedShopStatus)
{
ShopStatusList.Add(i.Text);
}
foreach (var i in checkedCustomerType)
{
CustomerTypeList.Add(i.Text);
}
foreach (var i in checkedCustomer)
{
CustomerList.Add(i.Text);
}
foreach (var i in checkedReseller)
{
ResellerList.Add(i.Text);
}
foreach (var i in checkedState)
{
StateList.Add(i.Text);
}
foreach (var i in checkedProjectManager)
{
ProjectManagerList.Add(i.Text);
}
foreach (var i in checkedSalesRepresentative)
{
SalesRepresentativeList.Add(i.Text);
}
DataTable designStatusParameters = ToStringDataTable(DesignStatusList);
DataTable shopStatusParameters = ToStringDataTable(ShopStatusList);
DataTable customerTypeParameters = ToStringDataTable(CustomerTypeList);
DataTable customerParameters = ToStringDataTable(CustomerList);
DataTable resellerParameters = ToStringDataTable(ResellerList);
DataTable stateParameters = ToStringDataTable(StateList);
DataTable projectManagerParameters = ToStringDataTable(ProjectManagerList);
DataTable salesRepresentativerParameters = ToStringDataTable(SalesRepresentativeList);
}
Change ToStringDataTable to an Extension Method. Then:
var designStatusParameters = cboDesignStatus.CheckBoxItems.Where(x => x.Checked)
.Select(i => i.Text).ToList().ToStringDataTable();
You can even write the extension method for your control in a way that performs filtering, projection and converting to data table for you then you can have:
var designStatusParameters = cboDesignStatus.ToStringDataTable();
You can cut out all the foreach loops by using Linq's Select():
For example:
var DesignStatusList =
cboDesignStatus.CheckBoxItems
.Where(x => x.Checked)
.Select(i => i.Text)
.ToList();
That will leave you with a List<string> containing all the Text properties from the checked CheckBoxes.
You could even skip declaring the list and combine that with your DataTable creation lines:
var designStatusParameters = ToStringDataTable(
cboDesignStatus.CheckBoxItems
.Where(x => x.Checked)
.Select(i => i.Text)
.ToList());
I would suggest putting this in a method of its own rather than repeating this over and over for each group of checkboxes.
Just keep in mind that less lines of code doesn't mean faster performance. It still has to iterate through the lists to find the right values. But it is much more readable than being hit in the face with a wall of repetitive code.
You don't need those many foreach rather re-factor to a single method like
public void AddToList(List<string> listToAdd, List<CheckBox> listToIterate)
{
foreach (var i in listToIterate)
{
listToAdd.Add(i.Text);
}
}
You are taking unnecessary expicit steps making your code way more verbose than it should be.
You are doing in separate steps:
Make an empty list.
Filter data
Iterate filtered data and add it to the empty list.
When you can do:
var newList =
someCollection.Where(someFilter)
.Select(someProjection)
.ToList();
That will make the code much more readable.
And, if you are in the mood, you can even make a helper method where you pass in someCollection, someFilter and someProjection and returns a list of something.
The code below isn't quite right, but I'd recommend that you build one generic method that returns a DataTable and you call that method over and over. Something like this:
public DataTable getDataTable( CheckBox yourCheckBox)
{
DataTable returnTable = new DataTable();
List<string> tempList = new List<string>();
var checkedDesignStatus = yourCheckBox.CheckBoxItems.Where(x => x.Checked);
foreach (var i in checkedDesignStatus)
{
tempList.Add(i.Text);
}
returnTable = ToStringDataTable(tempList);
return returnTable;
}
Create method (maybe local method?)
DataTable CheckedToDataTable(YourContainerType container)
=> ToStringDataTable(container.CheckBoxItems.Where(x => x.Checked).Select(x => x.Text).ToList());
i have two string array
string[] oldname = ["arun","jack","tom"];
string[] newname = ["jack","hardy","arun"];
here i want compare these two string arrays to get these distinct values separately like :
oldname = ["tom"];
newname = ["hardy"];
how to achieve these ...
string[] oldNameDistinct = oldname.Where(s => !newname.Contains(s)).ToArray();
string[] newNameDistinct = newname.Where(s => !oldname.Contains(s)).ToArray();
Let the two arrays were defined like the following:
string[] oldname = new[] { "arun", "jack", "tom" };
string[] newname = new string[] { "jack", "hardy", "arun" };
Then you can use the Extension method .Except to achieve the result that you are looking for. Consider the following code and the working example
var distinctInOld = oldname.Except(newname);
var distinctInNew = newname.Except(oldname);
Try this :
string[] oldname = new string[] { "arun", "jack", "tom" };
string[] newname = new string[] { "jack", "hardy", "arun" };
List<string> distinctoldname = new List<string>();
List<string> distinctnewname = new List<string>();
foreach (string txt in oldname)
{
if (Array.IndexOf(newname, txt) == -1)
distinctoldname.Add(txt);
}
foreach (string txt in newname)
{
if (Array.IndexOf(oldname, txt) == -1)
distinctnewname.Add(txt);
}
//here you can get both the arrays separately
Hope this help :)
string[] oldname = new []{"arun","jack","tom"};
string[] newname = new []{"jack","hardy","arun"};
// use linq to loop through through each list and return values not included in the other list.
var distinctOldName = oldname.Where(o => newname.All(n => n != o));
var distinctNewName = newname.Where(n => oldname.All(o => o != n));
distinctOldName.Dump(); // result is tom
distinctNewName.Dump(); // result is hardy
I have a varray string:
string[] imgList = new[] { };
And I retrieve the list of files:
DirectoryInfo directory = new DirectoryInfo(path);
FileInfo[] files = directory.GetFiles("*.jpg");
I want to add in my varray using LINQ the result. Some like this:
imgList = files.Where(x => x.FullName).ToList();
How can I do that?
Change Where to Select, and ToList() to ToArray() in your query.
imgList = files.Select(x => x.FullName).ToArray();
Something like this:
DirectoryInfo directory = new DirectoryInfo(path);
FileInfo[] files = directory.GetFiles("*.jpg");
string[] imgList = files.Select(p => p.Name).ToArray();
// or, without LINQ, probably a little faster:
string[] imgList = Array.ConvertAll(files, p => p.Name);
Note that in both cases you don't need to create the array beforehand, because a new array is returned by the Array.Convert/.ToArray().
There is a method that returns an array, as well the method you're using which returns a List<T>, so try:
imgList = files.Select(x => x.FullName).ToArray();
You have some error in your code.
First you have an incorrect string array declaration,
second you are trying convert .ToList() to string array. So try something like this
string[] imgList = new string[] { };
DirectoryInfo directory = new DirectoryInfo(path);
FileInfo[] files = directory.GetFiles("*.jpg");
imgList = files.Where(x => x.FullName == "myCondition").Select(x => x.FullName).ToArray();
I would like to know what the most efficient way of converting a FileSystemInfo to a string array is - My code as is follows:
string[] filePaths;
DirectoryInfo di = new DirectoryInfo(batchDirectory);
FileSystemInfo[] files = di.GetFileSystemInfos();
filePaths = files.OrderBy(f => f.CreationTime);
I tried:
filePaths = files.OrderBy(f => f.CreationTime).ToArray;
but had no luck
Try this:
filePaths = files.OrderBy(f => f.CreationTime).Select(x => x.FullName).ToArray();
Add parenthesis () to Array;
files.OrderBy(f => f.CreationTime).ToArray();
i am learning c# and have the following problem, i can not find a solution.
the code i am trying is:
string theString = "aaa XXX,bbb XXX,ccc XXX,aaa XXX";
List<string> listFromTheString= new List<string>(theString.Split(','));
List<string> listOfFoundItems = new List<string>();
for (int i = 0; i < (listFromTheString.Count); i++)
{
if(listFromTheString[i].Contains("aaa"))
{
listOfFoundItems.Add(listFromTheString[i]);
}
}
I would like to iterate through the list and create new items in a new list if a special keyword is found. The list listOfFoundItems does not get filled with the founds.
can you please give me a hint what i am doing wrong?
You can accomplish this more succinctly with LINQ:
string theString = ("aaa XXX,bbb XXX,ccc XXX,aaa XXX");
List<string> listFromTheString = new List<string>(theString.Split(','));
List<string> listOfFoundItems = listFromTheString.Where(s => s.Contains("aaa")).ToList();
The code you provided does work, though.
Here's an alternate, one-line version:
List<string> listOfFoundItems = theString.Split(',').Where(s => s.Contains("aaa")).ToList();
theString.Split(',').Where(p=>p.Contains("aaa")).ToList()
I know you want to fix your algorithm, but once you do, consider grokking this expression:
listofFoundItems = (from s in theString.Split(',')
where s.Contains("aaa")
select s).ToList();
The code you provide works fine. Given that, I suspect you may be having some string comparison issues.
This code may work better for you:
const string given = "aaa XXX,bbb XXX,ccc XXX,aaa XXX";
var givenSplit = new List<string>(given.Split(','));
var listOfFoundItems = new List<string>();
foreach(var item in givenSplit.Where(g => g.IndexOf("aAa", StringComparison.InvariantCultureIgnoreCase) > -1))
{
listOfFoundItems.Add(item);
}
// two items are added
string theString = ("aaa XXX,bbb XXX,ccc XXX,aaa XXX");
List<string> listFromTheString = new List<string>(theString.Split(','));
List<string> listOfKeywords = new List<string> { "aaa" };
List<string> found = (from str in listFromTheString
where listOfKeywords.Any(keyword => str.Contains(keyword))
select str).ToList<string>();