how to exclude items from List<RegistryPathData> - c#

I have a string array and a list and data is like below,
string[] str = new string[2] { "Prod1", "Prod2" };
List<RegistryPathData> data = new List<RegistryPathData>
{
new RegistryPathData{AppName="test1", RegPath="Prod1|Version"},
new RegistryPathData{AppName="test2", RegPath="Prod2|Version"},
new RegistryPathData{AppName="test3", RegPath="Prod3|Version"},
new RegistryPathData{AppName="test4", RegPath="Prod4|Version"},
new RegistryPathData{AppName="test5", RegPath="Prod5|Version"},
};
Now I want to exclude items from List<RegistryPathData> which is NOT matching with string array (prod1 & prod2). Need to exclude below 2, how to do this?
new RegistryPathData{AppName="test1", RegPath="Prod1|Version"},
new RegistryPathData{AppName="test2", RegPath="Prod2|Version"},

Use List.RemoveAll() function like this.
data.RemoveAll(d => str.Contains(d.RegPath.Split('|')[0]));

Use the Where method from LINQ and then check if any of the strings inside the str array match with the RegPath of the current object. Like this:
List<RegistryPathData> dataOnlyProd1And2 = data
.Where(rpd => str.Any(s => rpd.RegPath.StartsWith(s)))
.ToList();

You can use the LINQ .Where() method to filter a sequence of values based on a predicate.
data.Where(d => !str.Contains(d.RegPath.Split('|')[0]));
This means filter out the items in the list where the string up to the first pipe character is not contained in the str array.

Related

C# Split - Split on list dont return all the wanted strings

I'm fairly new to C#, and i've come across a problem trying to split on list elements.
I have a resource file containing string properties as such:
ResourceFile
ResourceFile
I've collected them in a List as:
public List<String> RawNewsList1 = new List<String>()
{
{Resource.NewsContentAndroid1},
{Resource.NewsMetaAndroid1},
};
I'm trying to split on the semicolons but only get results from my second list item.
My split look like this:
public void FilterRawNews()
{
String[] seperator = { ";;;" };
String[] filteredList1 = { "" };
for (int i = 0; i < RawNewsList1.Count; i++) {
filteredList1 = RawNewsList1[i].Split(seperator, 5,
StringSplitOptions.RemoveEmptyEntries);
}
foreach (String s in filteredList1)
{
Console.WriteLine(s);
}
}
Its only prints:
110
2.8
02-07-2020
What am i doing wrong?
Thanks in advance!
The filteredList1 variable is first filled with data from your the first resource, then at the next loop the variable's content is replaced with the data coming from the second resource.
You can use a List<string> instead that has the AddRange method to continuosly add elements to the list
List<string> filteredList1 = new List<string>();
for (int i = 0; i < RawNewsList1.Count; i++) {
filteredList1.AddRange(RawNewsList1[i].Split(seperator, 5,StringSplitOptions.RemoveEmptyEntries));
}
From this we could simplify the code to one-liner with
filteredList = RawNewsList1.SelectMany(a => a.Split(seperator,5, StringSplitOptions.RemoveEmptyEntries)).ToList();
So, what's happen in that single line? That syntax is used when you work with objects that can be treated as a sequence of data. In this context your array RawNewsList1 is a sequence of data and we can use the IEnumerable extensions brought to us by using the Linq namespace. The SelectMany extension requires a lambda expression ( a => ....) that is used to produce the instructions where each element of the sequence (a) is passed to an expression that returns another sequence of data (the array returned by Split). The sequence returned is accumulated to the sequence produced by the next elements from the original RasNewsList1. Finally the accumulated sequence is materialized with the call to ToList()
You are overwriting filteredList1 in each iteration.
That is why you only get the last result.
Just declare filteredList1 as a list and and use AddRange().
Edit: or use LINQ:
var raw = new List<string>() { "111;;;222", "333;;;444" };
String[] seperator = { ";;;" };
var filterlist1 = raw.SelectMany(r => r.Split(seperator, 5, StringSplitOptions.RemoveEmptyEntries)).ToList();

In C # how to pass string.empty in a list of string

i have a list of string
Emails = new List<string>() { "R.Dun#domain.co.nz", "S.Dun#domain.co.nz" }
now i want to pass string.empty to first value of list
something like
policy.Emails = new List<string>(){string.Empty};
how to put a loop for e.g. for each value of list do something.
you can directly set the first element as string.Empty:
policy.Emails[0]=string.Empty;
You can use indexof function for finding a string in the list as below,
List<string> strList = new List<string>() { "R.Dun#domain.co.nz", "S.Dun#domain.co.nz" };
int fIndex = strList.IndexOf("R.Dun#domain.co.nz");
if(fIndex != -1)
strList[fIndex] = string.Empty;
Or if you want to replace first item with string.Empty then as dasblinkenlight mentioned you can do using the index directly,
strList[0] = string.Empty
Hope it helps.
You can prepend string.Empty to an existing list with concat:
var emails = new List<string> {"R.Dun#domain.co.nz", "S.Dun#domain.co.nz"};
policy.Emails = new[] {string.Empty}.Concat(emails).ToList();
Now policy.Emails looks like this:
{"", "R.Dun#domain.co.nz", "S.Dun#domain.co.nz"}
If you would like to replace the first item, use Skip(1) before concatenating:
policy.Emails = new[] {string.Empty}.Concat(emails.Skip(1)).ToList();
To generalize, replacing the initial n values with empty strings would look like this:
policy.Emails = Enumerable.Repeat(string.Empty, 1).Concat(emails.Skip(n)).ToList();
Note: It goes without saying that if you do not mind modifying the list in place, the simplest solution is to do
emails[0] = string.Empty;
If you want to add an empty string at the beginning of a list you could do:
emails.Insert(0, string.Empty);

Transforming List<string> into a tokenised string

I have a list of strings in a List container class that look like the following:
MainMenuItem|MenuItem|subItemX
..
..
..
..
MainMenuItem|MenuItem|subItem99
What I am trying to do is transform the string, using LINQ, so that the first item for each of the tokenised string is removed.
This is the code I already have:
protected static List<string> _menuItems = GetMenuItemsFromXMLFile();
_menuItems.Where(x => x.Contains(menuItemToSearch)).ToList();
First line of code is returning an entire XML file with all the menu items that exist within an application in a tokenised form;
The second line is saying 'get me all menu items that belong to menuItemToSearch'.
menuItemToSearch is contained in the delimited string that is returned. How do I remove it using linq?
EXAMPLE
Before transform: MainMenuItem|MenuItem|subItem99
After transform : MenuItem|subItem99
Hope the example illustrates my intentions
Thanks
You can take a substring from the first position of the pipe symbol '|' to remove the first item from a string, like this:
var str = "MainMenuItem|MenuItem|subItemX";
var dropFirst = str.Substring(str.IndexOf('|')+1);
Demo.
Apply this to all strings from the list in a LINQ Select to produce the desired result:
var res = _menuItems
.Where(x => x.Contains(menuItemToSearch))
.Select(str => str.Substring(str.IndexOf('|')+1))
.ToList();
Maybe sth like this can help you.
var regex = new Regex("[^\\|]+\\|(.+)");
var list = new List<string>(new string[] { "MainMenuItem|MenuItem|subItem99", "MainMenuItem|MenuItem|subItem99" });
var result = list.Where(p => regex.IsMatch(p)).Select(p => regex.Match(p).Groups[1]).ToList();
This should work correctly.

Find all filenames that contain whitespace

I have a big list of filenames, some of which contain whitespace, for example
"\project summary version 2.xls"
or
"\production q3.pdf"
These file names are stored in object on string format.
Q: I would like to be able to query the object with maybe linq and collect all these illegal filenames together?
You can do something like this:
List<string> filenames = ...
List<string> filenamesWithSpaces = filenames.Where(f => f.Contains(" ")).ToList();
You have many options.
One way I'd do this would be to use string.Split and check it's result:
List<string> filenames = new List<string>(); // fill this list in some way.
var filesResult = filenames.Select(f => new { Filename = f, HasSpaces = f.Split(' ').Count() > 1 });
var filesWithSpaces = filesResult.Where(f => f.HasSpaces);

Ask for a linq to manipulate arrays of array

I have an array containing following elements
{Mark=90, Students={"Tom","Marry","Jack"}},
{Mark=50, Students={"Niko","Gary","David"}},
{Mark=70, Students={"John","Andy","Amy"}}
I want a Linq sentence to convert them to
{Mark=90, name="Tom"},
{Mark=90, name="Marry"},
{Mark=90, name="Jack"},
{Mark=50, name="Niko"},
{Mark=50, name="Gary"},
{Mark=50, name="David"},
{Mark=70, name="John"},
{Mark=70, name="Andy"},
{Mark=70, name="Amy"}
How could I do?
You could project to an anonymous class (or a real class if you need the sequence outside of your current method):
var results = from x in myArray
from s in x.Students
select new { x.Mark, name = s };
Use SelectMany:
data.SelectMany(
item => Students.Select(
student => new {Mark = item.Mark, name=student.Name}
)
);

Categories