List<string> how to get a specific string - c#

Im having a List, and the count of the list i 4. Now i want to get a specific string, and remove it from the list. I've tried with some code, and i thought that was enough, but my mistake. I think i'm close.! "navn" is a name which are achieved from a textbox. "strings" are my List strings..
if (strings.Contains(navn, StringComparer.OrdinalIgnoreCase))
{
Console.WriteLine("going inside");
strings.Remove(navn);
listBox_varer.Items.Clear();
string pr = "";
int i = 0;
for (i = 0; i <= (strings.Count - 1); i++)
{
pr = strings[i] + "\n";
listBox_varer.Items.Add(pr);
}
}
else
{
Console.WriteLine("going in else");
}

Your code compares with ignore case, but the remove method doesn't. I would do something like this:
string match = strings.FirstOrDefault(c => String.Equals(c, navn, StringComparison.InvariantCultureIgnoreCase));
if (match != null)
{
Console.WriteLine("going inside");
strings.Remove(match);
listBox_varer.Items.Clear();
for (int i = 0; i <= (strings.Count - 1); i++)
{
string pr = string.Concat(strings[i], Environment.NewLine);
listBox_varer.Items.Add(pr);
}
}
else
{
Console.WriteLine("going in else");
}

Assuming that your problem is to have the listbox reflecting your changing to the list, I have a short solution for you:
ObservableCollection<string> strings = new ObservableCollection<string>();
listBox.DataSource = strings;
strings.Remove(navn);

I think strings.Remove Remove function not compare by OrdinalIgnoreCase.
for(i=0;i<strings.Count-1;i++){
if(strings[i].Equals(navn,StringComparer.OrdinalIgnoreCase)){
strings.RemoveAt(i);
break;
}
}

The problem is that you have found the item ignoring the case StringComparer.OrdinalIgnoreCase. So you have found "foo" ignoring the case in ("Foo", "Bar") and you're trying to remove "foo" which is not in the list.
Try not to ignore the case or use LINQ
strings.RemoveAll(s =>
String.Equals(s, navn, StringComparison.OrdinalIgnoreCase));

If your problem is, that you cannot ensure that the value to be remved is entered in the right case, then this will help you:
var entryToRemove = strings.FirstOrDefault(item => item.ToUpper(CultureInfo.InvariantCulture) == navn.ToUpper());
if (entryToRemove != null)
{
strings.Remove(entryToRemove);
}

Related

Get the list of items matching a specific pattern of string

I have a C# model LedgerEntity.
public class LedgerEntity
{
public string AccountNumber{get;set;}
public string Accountlevel{get;set;}
public string AccountName{get;set;}
}
Also I have a list of items of that model class like below
List<LedgerEntity> items=new List<LedgerEntity>();
items=[
{"AccountNumber":"07-01-GRP_10095-81120000","AccountLevel":"Group","AccountName":"JPM"},
{"AccountNumber":"G3-80-GRP_10895-8112SLC0","AccountLevel":"Group","AccountName":"CIT"},
{"AccountNumber":"1C-MULTI-2851170-MULTI_8113xxxx","AccountLevel":"Group","AccountName":"BON"},
{"AccountNumber":"07-MULTI-MULTI_NONCORE-MULTI","AccountLevel":"Group","AccountName":"CUK"}}
]
My requirement is some thing like this.
I need to get all the records which contains
"GRP_*8112(* can have any value like 10095- or 10895- etc...)" in `AccountNumber. Then remove "GRP_" from the record and add "70" in front of the 3rd hyphen.
Example: 07-01-GRP_10095-81120000 --> 07-01-1009570-81120000
also update the Accountlevel of that matched records from Group to Individual.
My expected output is something like this.
matchedItems=[
{"AccountNumber":"07-01-1009570-81120000","AccountLevel":"Individual","AccountName":"JPM"},
{"AccountNumber":"G3-80-1089570-8112SLC0","AccountLevel":"Individual","AccountName":"CIT"},
{"AccountNumber":"1C-MULTI-2851170-MULTI_8113xxxx","AccountLevel":"Group","AccountName":"BON"},
{"AccountNumber":"07-MULTI-MULTI_NONCORE-MULTI","AccountLevel":"Group","AccountName":"CUK"}}
]
Please help me on this.
try this
foreach (var item in items)
{
var grpIndex = item.AccountNumber.IndexOf("GRP_");
if (grpIndex >= 0)
{
var numberIndex = item.AccountNumber.Substring(grpIndex + 4).IndexOf("8112");
if (numberIndex >= 0)
{
item.AccountNumber = item.AccountNumber.Replace("GRP_", "");
item.Accountlevel = "Individual";
var i = 0;
var counter = 0;
foreach (var ch in item.AccountNumber)
{
if (ch == '-') counter++;
if (counter == 3) break;
i++;
}
if (counter == 3) item.AccountNumber = item.AccountNumber.Insert(i, "70");
}
}
}
your problem can be solved with Regex with an expression like this for example:
(10(8|0)95)
You can use following code:
items.Where(item => Regex.IsMatch(item.AccountNumber, #"10(8|0)95)"))

remove split lines by index with same value from list

-from the list an example is 9120038560640 occurs twice or could be more than that.
-lines stored in List<.string> items = File.ReadAllLines(filepath).ToList();
-every line is split in semi colon.
-second index or [1] should compare to all of the lines and remove with found matched.
363193;9120038560640;7,11;9,99 <---- must be remove
363195;9120038560641;9,81;14,99
363194;9120038560640;9,81;14,99 <--- must be remove
363196;9120038560642;9,81;14,99
363197;9120038560643;9,81;14,99
....
..
.
btw. my file has 25,000++ items.
thank you
okay i got the answer and this is working
items = items.Where(x => x.Split(';')[columnIndex] != "").OrderBy(x => x.Split(';')[columnIndex]).ToList();
List<.string> _items = items.ConvertAll(z => z); //I make independent copy
string[] itemsArr = items.ToArray();
int countA = 0;
foreach (string itemArr in itemsArr)
{
List<int> groupDuplicates = new List<int>();
for (int a = countA; a < itemsArr.Count(); a++)
{
if (itemArr != itemsArr[a])
{
if (itemArr.Split(';')[columnIndex] == itemsArr[a].Split(';')[columnIndex]) //if matched then add
{
groupDuplicates.Add(a); // listing index to be remove
}
else
break; //no way to go through the bottom of the list and also to make the performance faster
}
countA++;
}
if (groupDuplicates.Count() != 0)
{
groupDuplicates.Add(groupDuplicates.First() - 1); //I add here the first item in duplicates
foreach (int m in groupDuplicates)
{
_items.Remove(items.ElementAt(m)); //remove by item not by index
}
}
}

Filtering elements of an array

I have an array as
That is, each item has its category in the following index.
I need all the items whose category are TotalNumbers and CurrentNumbers.
I tried
int i = 1;
foreach (string item in statsname)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
{
comboBox1.Items.Add(statsname[i-1]);
i++;
i++;
}
comboBox1.SelectedIndex = 0;
}
Apparently this does not checks for what I need correctly.
How do I need to modify my codes to get what i need ?
Seems it's better to use a for loop instead of foreach:
for (int i = 1; i < statsname.Length; i += 2)
{
//only number type stats are added to the comboboxes.
if ((statsname[i].ToUpperInvariant()==("TOTALNUMBER")) || ((statsname[i].ToUpperInvariant()==("CURRENTNUMBER"))))
comboBox1.Items.Add(statsname[i-1]);
}
Linq comes to rescue!
var listItems = from s in statsname where s.Equals("TOTALNUMBER", StringComparison.InvariantCultureIgnoreCase) || s.Equals("CURRENTNUMBER", StringComparison.InvariantCultureIgnoreCase) select new ListItem(s);
comboBox1.AddRange(listItems);
Code not tested or compiled, but you can have an idea of what i said.
var filteredValues = Array.FindAll(source, s => s.ToUpperInvariant() == "TOTALNUMBER" ||
s.ToUpperInvariant() == "CURRENTNUMBER").ToList()
I am not sure why you are using index in an foreach loop. The below code should work for you
foreach (string item in statsname)
{
if ( item.ToUpper() == "TOTALNUMBER" || item.ToUpper() == "CURRENTNUMBER")
{
comboBox1.Items.Add(item);
}
}
comboBox1.SelectedIndex = 0;

c# search string in txt file

I want to find a string in a txt file if string compares, it should go on reading lines till another string which I'm using as parameter.
Example:
CustomerEN //search for this string
...
some text which has details about the customer
id "123456"
username "rootuser"
...
CustomerCh //get text till this string
I need the details to work with them otherwise.
I'm using linq to search for "CustomerEN" like this:
File.ReadLines(pathToTextFile).Any(line => line.Contains("CustomerEN"))
But now I'm stuck with reading lines (data) till "CustomerCh" to extract details.
If your pair of lines will only appear once in your file, you could use
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.Skip(1) // optional
.TakeWhile(line => !line.Contains("CustomerCh"));
If you could have multiple occurrences in one file, you're probably better off using a regular foreach loop - reading lines, keeping track of whether you're currently inside or outside a customer etc:
List<List<string>> groups = new List<List<string>>();
List<string> current = null;
foreach (var line in File.ReadAllLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
current = new List<string>();
else if (line.Contains("CustomerCh") && current != null)
{
groups.Add(current);
current = null;
}
if (current != null)
current.Add(line);
}
You have to use while since foreach does not know about index. Below is an example code.
int counter = 0;
string line;
Console.Write("Input your search text: ");
var text = Console.ReadLine();
System.IO.StreamReader file =
new System.IO.StreamReader("SampleInput1.txt");
while ((line = file.ReadLine()) != null)
{
if (line.Contains(text))
{
break;
}
counter++;
}
Console.WriteLine("Line number: {0}", counter);
file.Close();
Console.ReadLine();
With LINQ, you could use the SkipWhile / TakeWhile methods, like this:
var importantLines =
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.TakeWhile(line => !line.Contains("CustomerCh"));
If you whant only one first string, you can use simple for-loop.
var lines = File.ReadAllLines(pathToTextFile);
var firstFound = false;
for(int index = 0; index < lines.Count; index++)
{
if(!firstFound && lines[index].Contains("CustomerEN"))
{
firstFound = true;
}
if(firstFound && lines[index].Contains("CustomerCh"))
{
//do, what you want, and exit the loop
// return lines[index];
}
}
I worked a little bit the method that Rawling posted here to find more than one line in the same file until the end. This is what worked for me:
foreach (var line in File.ReadLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
{
current = new List<string>();
current.Add(line);
}
else if (line.Contains("CustomerEN") && current != null)
{
current.Add(line);
}
}
string s = String.Join(",", current);
MessageBox.Show(s);

c# get a specific element of a HashSet

I want to get an element of a HashSet only if it contains a specific string in it. i tried
the code below, but i dont get anything... like no matching. but this cant happen cause the UnKnown counter is always 0.
if (!IsbnAuth.Contains(RecTitle))
{
Unknown++;
}
else
{
for (int i = 0; i < IsbnAuth.Count(); i++)
{
if (IsbnAuth.ElementAt(i).Contains(RecTitle))
{
System.Console.WriteLine(IsbnAuth.ElementAt(i));
//isbn = IsbnAuth.ElementAt(i).Substring(0, IsbnAuth.ElementAt(i).IndexOf("\t"));
isbn = IsbnAuth.ElementAt(i).Split(' ')[0];
break;
}
}
}
Any ideas? the problem is not at the RecTitle cause even if it was just a single char instead, the result would be the same.
IsbnAuth is the HashSet.
EDIT: IsbnAuth declaration
HashSet<String> IsbnAuth = new HashSet<String>();
foreach (String line in IsbnAuthors)
{
IsbnAuth.Add(line.Trim());
}
System.Console.WriteLine(IsbnAuth.Count);
This is the first problem:
if (!IsbnAuth.Contains(RecTitle))
{
Unknown++;
}
That checks whether the set contains the whole string, as a complete element. It sounds like it doesn't.
I suspect you really want:
bool found = false;
foreach (String element in IsbnAuth)
{
if (element.Contains(RecTitle))
{
isbn = element.Split(' ')[0];
found = true;
break;
}
}
if (!found)
{
Unknown++;
}
Or even better:
string isbn = IsbnAuth.Where(x => x.Contains(RecTitle))
.Select(x => x.Split(' ')[0])
.FirstOrDefault();
if (isbn == null)
{
Unknown++;
}
It's worth being aware that a HashSet is in a fundamentally unpredictable order - so if there are multiple matches here, you'll end up with an arbitrary result. Is that really what you want?
It seems to me that you are storing mulitple informations held in one string in your Hastable. I would do it in that way:
public class Info
{
public string ISBN { get; set; }
public string Title { get; set; }
}
later in code:
List<Info> isbnAuth = new List<Info>();
foreach (String line in IsbnAuthors)
{
isbnAuth.Add(new Info { ISDN = line.Split(' ')[0], Title = line.Split(' ')[1] });
}
You can search an item like this:
var itemFound = isbnAuth.FirstOrDefault(item => item.Title == RecTitle);
if (itemFound != null)
{
isbn = itemFound.ISBN;
}

Categories

Resources