How to compare values in 2 lists - c#

I have a list as Users = new List<string>();
I have another List, List<TestList>();
UsersList = new List<string>();
I need to compare the values from Users with TestList.Name. If the value in TestList.Name is present in Users, I must must not add it to UsersList, else, I must add it to UsersList.
How can I do that using Linq?

It looks to me like you want:
List<string> usersList = testList.Select(x = > x.Name)
.Except(users)
.ToList();
In other words, "use all the names of the users in testList except those in users, and convert the result to a List<string>".
That's assuming you don't have anything in usersList to start with. If usersList already exists and contains some values, you could use:
usersList.AddRange(testList.Select(x = > x.Name).Except(users));
Note that this won't take account of the existing items in usersList, so you may end up with duplicates.

Do a loop on you list - for example :
foreach (string s in MyList)
{
if (!MyList2.Contains(s))
{
// Do whatever ; add to the list
MyList2.Add(s);
}
}
..that's how I interpreted you question

Related

How to remove duplicates from the list in C#

Please help me to fix this issue. My dropdown list looks something like this mentioned below.
Client
Contractor,Contractor,Contractor,Manager
Contractor,Manager
Manager
Operator
Viewer
I want to remove the duplicates and my output should be like :
Client
Contractor
Manager
Operator
Viewer
This is my code mentioned below:
Property:
public List<string> TeamRoleNames => TeamRoleUids.Select(MainRoles.GetRoleName).ToList();
Display Method:
{
result += " ; TeamRoleNames=" + this.TeamRoleNames;
}
GetRole Method:
{
string roleName;
if (RoleNameByUid.TryGetValue(roleUid, out roleName))
{
return roleName;
}
return null;
}
I have tried with Distinct Method mentioned below, But did not work like the output what I wanted!
public List<string> TeamRoleNames => TeamRoleUids.Select(MainRoles.GetRoleName).Distinct().ToList();
How can I fix this? Can anyone help?
Having elements comma separated require you to split them first to have an homogenous collection then do the distinct
// get the comma separated values out as 1 value each
// for that you can use split, remove empty and select many
// which will return as a single level list (flat)
var result = TeamRoleUids.SelectMany(o => o.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)).Distinct().ToList();
Consider converting the list to a set (hashset) since sets as a data structure doesn't allow duplicates.
More about hashsets form official documentation.
So, the solution would be similar to the following:
var hashSet = new HashSet<YourType>(yourList);
example:
var hashSet = new HashSet<string>(TeamRoleUids);
then converting it back toList() will remove duplicates.
If you have already tried Distinct and it hasn't worked, then you could do the following;
Split your string list to a List<string>
List<string> result = TeamRoleNames.Split(',').ToList();
Then when you're adding them to the dropdwon, check to see if the role is already in the dropdown. If so, move on, else add to the dropdown.
So something like
foreach(var role in this.TeamRoleNames)
{
if(!result.contains(role))
result += " ; TeamRoleNames=" + role;
}
You can use SelectMany to flatten a enumeration containing a nested enumeration. Here, we create the nested enumeration by splitting the string at the commas:
string[] input = {
"Client",
"Contractor,Contractor,Contractor,Manager",
"Contractor,Manager",
"Manager",
"Operator",
"Viewer"
};
var roles = input
.SelectMany(r => r.Split(','))
.Distinct()
.OrderBy(r => r)
.ToList();
foreach (string role in roles) {
Console.WriteLine(role);
}
prints
Client
Contractor
Manager
Operator
Viewer

C# Comparing if two lists have the same order of items (alphabetical)

I'm facing a huge problem with comparing two lists. I just made copy of my first list and I tried to sort it. The problem is, I want to compare my original list and sorted one to see if they have same alphabetical order. I hope I provided enough information for my problem.
Thanks in advance
public void VerifyDataPrijave(string username)
{
List<string> listaTekstova = new List<string>(); //initializing new, empty List
var kartice = Repo.Kartice.CreateAdapter<Unknown>(false).Find(".//div[class='_63fz removableItem _95l5']");
foreach (var kartica in kartice) {
var slika = kartica.Find(".//tag[tagname='img']")[0];
var ime = slika.Find("following-sibling::div")[0];
string text = ime.GetAttributeValue("InnerText").ToString(); //loop through profile cards and getting Names as InnerText in variable text
listaTekstova.Add(text); //adding those "texts" I just found to an empty list initialized before
List<string> novaListaTekstova = new List<string>(listaTekstova); //clone (copy) of the very first one list
novaListaTekstova.Sort(); //sorting that list alphabetically (I suppose, not sure)
}
}
You can use SequenceEqual to compare to IEnumerables. In your case you can do something like this once all sorting has been done:
var isEqual = novaListaTekstova.SequenceEqual(listaTekstova);

c# remove everything in List collection after a particular index

I want to be able to remove all elements in a List<string> after a certain index
List<string> s_array= new List<string>();
s_array.Add("a");
s_array.Add("x");
s_array.Add("c");
s_array.Add("y");
s_array.Add("e");
s_array.Add("e");
s_array.RemoveAll(/* what goes here?*/);
What can i put in RemoveAll to achieve this? for example say i wanted to cut out everything from c onwards?
Not sure what all your parameters are, so it's hard to say what approach will be best.
Using RemoveAll(), you could do:
s_array.RemoveAll(x => s_array.IndexOf(x) > s_array.IndexOf("c"));
You could use the key words Take or Skip to help - Example:
var s_array = new List<string> {"a","x","c","y","e","e" };
var sorted = (from x in s_array orderby x select x);
var first3 = sorted.Take(3);
var last2 = sorted.Take(2).Skip(5);

ISharedPreferences deletes duplicates when inserted

For example, I have a simple List:
List<string> s = new List<string>();
s.Add("eg1");
s.Add("eg2");
s.Add("eg3");
s.Add("eg1");
Lets say I want to now insert in into my ISharedPreferences editor called editor:
editor.PutStringSet("eg", s);
Now, I want to access this list by doing this:
ICollection<string> eg= prefs.GetStringSet("eg", (ICollection<string>)new HashSet<string>());
List<string> s2 = eg.ToList<string>();
The problem is that I have duplicates like "eg1" in my list but the editor deletes them.
My question is how can I prevent the editor from deleting duplicates in my list?
Instead of your current list, you could store also the number of occurrences (or the indexes if they matter to you):
List<string> s = new List<string>();
s.Add("eg1:[0, 3]");
s.Add("eg2:[1]");
s.Add("eg3:[2]");

How do I remove duplicates from excel range? c#

I've converted cells in my excel range from strings to form a string list and have separated each item after the comma in the original list. I am starting to think I have not actually separated each item, and they are still one whole, trying to figure out how to do this properly so that each item( ie. the_red_bucket_01)is it's own string.
example of original string in a cell 1 and 2:
Cell1 :
the_red_bucket_01, the_blue_duck_01,_the green_banana_02, the orange_bear_01
Cell2 :
the_purple_chair_01, the_blue_coyote_01,_the green_banana_02, the orange_bear_01
The new list looks like this, though I'm not sure they are separate items:
the_red_bucket_01
the_blue_duck_01
the green_banana_02
the orange_bear_01
the_red_chair_01
the_blue_coyote_01
the green_banana_02
the orange_bear_01
Now I want to remove duplicates so that the console only shows 1 of each item, no matter how many there are of them, I can't seem to get my foreah/if statements to work. It is printing out multiple copies of the items, I'm assuming because it is iterating for each item in the list, so it is returning the data that many items.
foreach (Excel.Range item in xlRng)
{
string itemString = (string)item.Text;
List<String> fn = new List<String>(itemString.Split(','));
List<string> newList = new List<string>();
foreach (string s in fn)
if (!newList.Contains(s))
{
newList.Add(s);
}
foreach (string combo in newList)
{
Console.Write(combo);
}
You probably need to trim the strings, because they have leading white spaces, so "string1" is different from " string1".
foreach (string s in fn)
if (!newList.Contains(s.Trim()))
{
newList.Add(s);
}
You can do this much simpler with Linq by using Distinct.
Returns distinct elements from a sequence by using the default
equality comparer to compare values.
foreach (Excel.Range item in xlRng)
{
string itemString = (string)item.Text;
List<String> fn = new List<String>(itemString.Split(','));
foreach (string combo in fn.Distinct())
{
Console.Write(combo);
}
}
As mentioned in another answer, you may also need to Trim any whitespace, in which case you would do:
fn.Select(x => x.Trim()).Distinct()
Where you need to contain keys/values, its better to use Dictionary type. Try changing code with List<T> to Dictionary<T>. i.e.
From:
List<string> newList = new List<string>();
foreach (string s in fn)
if (!newList.Containss))
{
newList.Add(s);
}
to
Dictionary<string, string> newList = new Dictionary<string, string>();
foreach (string s in fn)
if (!newList.ContainsKey(s))
{
newList.Add(s, s);
}
If you are concerned about the distinct items while you are reading, then just use the Distinct operator like fn.Distinct()
For processing the whole data, I can suggest two methods:
Read in the whole data then use LINQ's Distinct operator
Or use a Set data structure and store each element in that while reading the excel
I suggest that you take a look at the LINQ documentation if you are processing data. It has really great extensions. For even more methods, you can check out the MoreLINQ package.
I think your code would probably work as you expect if you moved newList out of the loop - you create a new variable named newList each loop so it's not going to find duplicates from earlier loops.
You can do all of this this more concisely with Linq:
//set up some similar data
string list1 = "a,b,c,d,a,f";
string list2 = "a,b,c,d,a,f";
List<string> lists = new List<string> {list1,list2};
// find unique items
var result = lists.SelectMany(i=>i.Split(',')).Distinct().ToList();
SelectMany() "flattens" the list of lists into a list.
Distinct() removes duplicates.
var uniqueItems = new HashSet<string>();
foreach (Excel.Range cell in xlRng)
{
var cellText = (string)cell.Text;
foreach (var item in cellText.Split(',').Select(s => s.Trim()))
{
uniqueItems.Add(item);
}
}
foreach (var item in uniqueItems)
{
Console.WriteLine(item);
}

Categories

Resources