Compare string between listboxes - c#

I have two listboxes with several data, ListBox1 have this format:
C:\Users\Charlie\Desktop\Trials\Trial0004COP.txt
and in my ListBox2:
Trial0004COP
How can I check if Trial0004COP exists in my listbox1? I used Contain() but it doesn't work.

I would recommend something like:
var searchString = "Trial0004COP";
var isFound = false;
foreach(var name in listbox1.items)
{
if (Path.GetFileNameWithoutExtension(name).ToLower() == searchString.ToLower())
{
_IsFound = true;
break;
}
}
Note that in Windows, file names are case-preserving but not case-sensitive, so you need to check the file name ignoring its case.
You could do it in a single line in Linq, if that's your thing.
var searchString = "Trial0004COP";
var isFound = listBox1.Items.Cast<string>()
.Any(x => Path.GetFileNameWithoutExtension(x).ToLower() == searchString.ToLower());

What about:
bool found = listBox1.Items.Cast<string>()
.Where(x => x.Contains("Trial0004COP"))
.Any();
Or to make it more accurate use String.EndsWith() method but you also have to add ".txt" if you want to make it works:
bool found = listBox1.Items.Cast<string>()
.Where(x => x.EndsWith("Trial0004COP.txt"))
.Any();
Edit :
Hi Fuex, I'm using OpenFileDialog to select a file, then this file is
added to my listbox1 with all the Directory name. In my listbox2 I
read another file that contains several Trials000""" and add them to
it, I want to know if the file that I selected from the open dialog
exist in my listboz2
Yes can do it in this way:
bool found = false;
if(openFileDialog.ShowDialog() == DialogResult.OK){
found = listBox.Items.Cast<string>()
.Where(x => x.EndsWith(openFileDialog.FileName))
.Any();
if(!found)
MessageBox.Show(openFileDialog.FileName + " doesn't exist in listBox1"); //show a message
}

Using LINQ you can do:
listBox1.Items.Select(e => Path.GetFileNameWithoutExtension(e as string)).Contains("Trial0004COP");

Related

Is it possible to convert this foreach loop into a LINQ-to-XML loop?

I originally asked this question (Can we automatically add a child element to an XElement in a sortable manner?) and it was closed as a duplicate (how to add XElement in specific location in XML Document).
This is teh code that I have at the moment:
bool bInserted = false;
foreach (var weekDB in xdoc.Root.Elements())
{
DateTime datWeekDB = DateTime.ParseExact(weekDB.Name.LocalName, "WyyyyMMdd", CultureInfo.InvariantCulture);
if (datWeekDB != null && datWeekDB.Date > historyWeek.Week.Date)
{
// Insert here
weekDB.AddBeforeSelf(xmlHistoryWeek);
bInserted = true;
break;
}
}
if (!bInserted)
xdoc.Root.Add(xmlHistoryWeek);
It works fine. But I wondered if I can use LINQ to acheive the same thing? The linked answer suggests:
Search element you want to add and use Add method as shown below
xDoc.Element("content")
.Elements("item")
.Where(item => item.Attribute("id").Value == "2").FirstOrDefault()
.AddAfterSelf(new XElement("item", "C", new XAttribute("id", "3")));
But I don't understand how to end up with logic like that based on my codes logic.
I think the best way to think about it is: you are going to use LINQ to find a specific element. Then you will insert into the document based on what you found.
So something like this:
var targetElement = xdoc.Root.Elements()
.Where(weekDB => {
DateTime datWeekDB = DateTime.ParseExact(weekDB.Name.LocalName, "WyyyyMMdd", CultureInfo.InvariantCulture);
return datWeekDB != null && datWeekDB.Date > historyWeek.Week.Date;
})
.FirstOrDefault();
if (targetElement == null)
{
xdoc.Root.Add(xmlHistoryWeek);
}
else
{
targetElement.AddBeforeSelf(xmlHistoryWeek);
}

How to check if a string is in an array

I am trying to check whether a string is in an array and if continues even though the fileInfo.Name.Contains a string that is in files.Any:
\\FILES LIKE DATABASE.MDB IS IN C:PROJECTS\HOLON\DATABASE.MDB
**if (files.Any((fileInfo.Name.Contains)))**
\\DO SOMETHING
Console.WriteLine(
fileInfo.Name, fileInfo.Length,
If you alread have the filenames collected in an array, then you should either do it this way:
if (files.Any() && files.Contains(fileInfo.Name))
{
// Do something
}
If you just want to check if a file exists then you can use File.Exists:
if(System.IO.File.Exists(fileInfo.Name))
{
// Do Something
}
So you have a collection of full file paths? And you want to check if one or more of those list entries match with a specific file name?
Perhaps this would work for you:
string fileToSearch = "DATABASE.MDB";
bool found = files.Any(fileName => new FileInfo(fileName).Name.ToUpper() == fileToSearch.ToUpper());
Edit:
An alternative to constructing new FileInfo objects would be to use System.IO.Path:
bool found = files.Any(fileName => Path.GetFileName(fileName).ToUpper() == fileToSearch.ToUpper());
Edit 2:
On the other hand, if you want to search for a specific file name, and you want to use the result, you could do something like this:
var fileToSearch = "DATABASE.MDB";
var fileInfo =
(from f in files
let fi = new FileInfo(f)
where fi.Name.ToUpper() == fileToSearch.ToUpper()
select fi).FirstOrDefault();
if (fileInfo != null)
{
if (fileInfo.Exists)
{
Console.WriteLine($"{fileInfo.Name} ({fileInfo.Length} bytes).");
}
else
{
Console.WriteLine($"{fileInfo.Name} (does not exist).");
}
}
I used a LINQ query here for readability. You could use the extension methods (files.Select(f => new FileInfo(f)).Where(fi => fi.Name.ToUpper() == fileToSearch.ToUpper()).FirstOrDefault()) as well, but that's up to you.
if (Array.Exists(files, element => element.Contains(fileInfo.Name)))

Simple code to get specific item from a list

I have a list of a tags. I want to get an a tag which contains a string.
I used the below code and everything work fine.
string mainLink = "";
List<HtmlNode> dlLink = new List<HtmlNode>();
dlLink = doc.DocumentNode.SelectNodes("//div[#class='links']//a").ToList();
foreach (var item in dlLink) {
if (item.Attributes["href"].Value.Contains("prefile"))
{
mainLink = item.Attributes["href"].Value;
}
}
but I want to write a simple code
var dlLink = doc.DocumentNode.SelectNodes("//div[#class='link']//a").ToList().Where(x => x.Attributes["href"].Value.Contains("prefile")).ToList().ToString();
But it does not work and I get nothing.
Your foreach is setting mainLink string, but your linq chain is using ToString on a List result.
Converting your code, you will have something like this:
mainLink = doc.DocumentNode.SelectNodes("//div[#class='links']//a")
.Where(item => item.Attributes["href"].Value.Contains("prefile"))
.Select(item => item.Attributes["href"].Value)
.Last();
I used Select to get only the href values, and getting the last as your foreach did, maybe you need to validate this last step, use a LastOrDefault, First, etc.
You can also use the Last or First instead of the Where condition:
mainlink = doc.DocumentNode.SelectNodes("//div[#class='links']//a")
.Last(item => item.Attributes["href"].Value.Contains("prefile"))
.Attributes["href"].Value;

Check if the value exists in a dropdown

I have a dropdown that contains Subjects.
What I did, I use the code below to get the values on that dropdown.
IList<IWebElement> allOptions = check.Options;
Then I declare a string that will handle all the values I have to verify if these values exist on that dropdown.
string[] subject = "Math", "Science", "History", "Calculus", etc...
I loop them to get how many subjects I have to check if they exist on the dropdown then verify it using Contains.
if (allOptions.Contains(subject[i]))
{
exist = true;
}
However, I am getting an error that cannot convert a string to OpenQA.Selenium.IWebElement.
Anyone has idea how to fix it?
Thank you.
You can use LINQ for this. Basically this code:
if (allOptions.Contains(subject[i]))
{
exist = true;
}
Can be replaced by a single line:
exist = allOptions.Any(x => x.Text == subject[i]);
Basically this code just checks if any element in the allOptions list has Text that matches subject[i]. If true, exist is now true, if false exist is now false.
Indeed, you cannot do that directly. The IWebElement contains a string property named Text, which is what you need to filter on. Like so:
var foundSubjects = allOptions.Where(o => subject.Contains(o.Text));
If you just need to find out if ALL the options are found in the subject array, do:
var optionsAreValid = allOptions.All(o => subject.Contains(o.Text));
Alternatively you could use Any to determine if at least one option exists in the subject array:
var isThereAValidOption = allOptions.All(o => subject.Contains(o.Text));
Try looping through the IList<IWebElement> instead:
int subjectCount = 0;
foreach (IWebElement element in allOptions)
{
if (subject.Contains(element.Text))
{
subjectCount++;
}
}
Use the Text property of the WebElement. it may be work for you

Get all items that match a DropLink option in Sitecore

This seems like it should be easy. Maybe it is and I'm just overthinking it. I have a bunch of items that have a category field set via a DropLink. I want to grab all of the items that match one of those options. E.g., Grab a list of all items where Category=Brochure. I can't seem to get the ID of the Droplink option to match against the Category option on the Item itself.
EDIT: Included current code by request.
public List<PoolDownload> Manuals
{
get
{
LookupField cat = (LookupField)this.Item.Fields["Category"];
return this.Downloads.Where(i => (i.Item.TemplateID == PoolDownload.TemplateId) &&
(i.Item.GlassCast<Pdp.Pool.Website.Business.Entities.PoolDownload>().Category.ToString() == cat.TargetID.ToString()))
.ToList();
}
}
I believe the problem is you're comparing a Guid.ToString() to a Sitecore.Data.ID.ToString(). These two statements return different values:
var guidToString = Sitecore.Context.Item.ID.Guid.ToString();
// "2a6a1d9a-be1d-411b-821a-7e63775280b3"
var idToString = Sitecore.Context.Item.ID.ToString();
// "{2A6A1D9A-BE1D-411B-821A-7E63775280B3}"
Cast the TargetID to a Guid as well and you should be good.
And to answer your question in your comment below about displaying the "Download Items" grouped by Category, you could use the GroupBy method, https://msdn.microsoft.com/en-us/library/bb534304(v=vs.110).aspx like this:
public IEnumerable<IGrouping<Guid, PoolDownload>> Manuals
{
get
{
LookupField cat = (LookupField)this.Item.Fields["Category"];
return this.Downloads.Where(i =>
i.Item.TemplateID == PoolDownload.TemplateId
&& i.Item.GlassCast<Pdp.Pool.Website.Business.Entities.PoolDownload>().Category.ToString() == cat.TargetID.Guid.ToString())
.GroupBy(i => i.Category);
}
}
And then, to loop over the results in the new Manuals property, you could do something like this:
foreach(var categoryGroup in Manuals)
{
var categoryGuid = categoryGroup.Key;
foreach(var download in categoryGroup)
{
var downloadInCurrentGroup = download.Item;
}
}

Categories

Resources