Is it possible to get unique records using Linq (C #)?

I got list<list<string>>

in list[x][0] are the entries from which I want to select unique entries, so such an entry will not be in any other list[x][0 ], when I select it, I would select the whole line list[x] . I did not find a suitable example for this in Linq, please help :(

EDIT

When John Skeet asks me to clarify, I cannot deny; -)

 list<list<string>> 

contains a list of row tables. Each row of the "table" contains several keys list[x][several_items] , and I want to get unique entries from the list β†’ FIRST value in this "table".

Thus:

 item[0] = "2","3","1","3" item[1] = "2","3","4","2" item[3] = "10","2" item[4]= "1","2" 

-> unique means that I can output the lines item[3] and item[4] as unique. because the first occurrence of a number / string is important.

If there are 2 or more entries / rows in the list ( item[x] of which first item (item[x][0]) exists more than once, this is not unique.

The first element of each list is important to determine uniqueness. Maybe it would be easier if someone could help find a way to find a non-unique β†’ so from the above example, I would only get the element [0] and the element [1] in the list

+3
source share
6 answers

EDIT: I updated the UniqueBy implementation below to be significantly more efficient, and only repeat the source code once.

If you understood correctly (the question is rather unclear - it would really help if you could give an example), this is what you want:

 public static IEnumerable<T> OnlyUnique<T>(this IEnumerable<T> source) { // No error checking :) HashSet<T> toReturn = new HashSet<T>(); HashSet<T> seen = new HashSet<T>(); foreach (T element in source) { if (seen.Add(element)) { toReturn.Add(element); } else { toReturn.Remove(element); } } // yield to get deferred execution foreach (T element in toReturn) { yield return element; } } 

EDIT: Well, if you only care about the first element of the list for uniqueness, we need to change it a bit:

 public static IEnumerable<TElement> UniqueBy<TElement, TKey> (this IEnumerable<TElement> source, Func<TElement, TKey> keySelector) { var results = new LinkedList<TElement>(); // If we've seen a key 0 times, it won't be in here. // If we've seen it once, it will be in as a node. // If we've seen it more than once, it will be in as null. var nodeMap = new Dictionary<TKey, LinkedListNode<TElement>>(); foreach (TElement element in source) { TKey key = keySelector(element); LinkedListNode<TElement> currentNode; if (nodeMap.TryGetValue(key, out currentNode)) { // Seen it before. Remove if non-null if (currentNode != null) { results.Remove(currentNode); nodeMap[key] = null; } // Otherwise no action needed } else { LinkedListNode<TElement> node = results.AddLast(element); nodeMap[key] = node; } } foreach (TElement element in results) { yield return element; } } 

You would call it with:

 list.UniqueBy(row => row[0]) 
+10
source

Something like this, maybe?

Now I'm sure this will work for you, given your clarification :)

 var mylist = new List<List<string>>() { new List<string>() { "a", "b", "c" }, new List<string>() { "a", "d", "f" }, new List<string>() { "d", "asd" }, new List<string>() { "e", "asdf", "fgg" } }; var unique = mylist.Where(t => mylist.Count(s => s[0] == t[0]) == 1); 

unique now contains the "d" and "e" records on top.

+2
source

Here is the code you need. It works great for me to select ONLY different values.

 //distinct select in LINQ to SQL with Northwind var myquery = from user in northwindDC.Employees where user.FirstName != null || user.FirstName != "" orderby user.FirstName group user by user.FirstName into FN select FN.First(); 
+2
source

Here are some Linq for you.

 List<List<string>> Records = GetRecords(); // List<List<string> UniqueRecords = Records .GroupBy(r => r[0]) .Where(g => !g.Skip(1).Any()) .Select(g => g.Single()) .ToList(); 
+1
source

You can save the list and index / dictionary :

 List<List<string>> values; Dictionary<string, List<string>> index; 

When you add an item to values, you also add a list to the index with a row as an index.

 values[x].Add(newString); index[newString] = values[x]; 

Then you can get the correct list:

 List<string> list = index[searchFor] 

You lose some (minimal) performance and memory when creating an index, but when you extract data, you get a lot.

If the string is not unique, you can also save List> to dictionary / index to allow multiple results on the index key.

Sorry, no Linq, it doesn’t look so cool, but you quickly browse and IMHO the search code is more clear.

0
source

I just go ahead and add this to the fray.

 using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { List<string> xx = new List<string>() { "xx", "yy", "zz" }; List<string> yy = new List<string>() { "11", "22", "33" }; List<string> zz = new List<string>() { "aa", "bb", "cc" }; List<List<string>> x = new List<List<string>>() { xx, yy, zz, xx, yy, zz, xx, yy }; foreach(List<string> list in x.Distinct()) { foreach(string s in list) { Console.WriteLine(s); } } } } } 
0
source

All Articles