有机会使用 Linq (C#) 获取唯一记录吗?

发布于 2024-07-16 17:34:18 字数 847 浏览 7 评论 0 原文

我在 list[x][0] 中有一个 list>

是我想从中选择唯一记录的记录,因此这样的记录不会在任何其他 list[x][0] 中,当我选择它时,我希望选择整行 list[x] 。 我在 Linq 中没有找到合适的示例,请帮助:(

编辑

当 Jon Skeet 要求我澄清时,我不能否认;-)

list<list<string>>

包含字符串表列表。 每个字符串“table”都包含几个键 list[x][several_items] 我想从 list-> 中获取唯一的记录 意思是“表”中的第一个项目。

因此:

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

-> 唯一意味着我可以将行 item[3] 和 item[4] 派生为唯一。 因为数字/字符串的第一次出现很重要。

如果有 2 个或更多记录/行(item[x],其中第一项 (item[x][0]) 在列表中存在多次,则它不是唯一的。

每个的第一个元素列表对于确定唯一性很重要。如果有人可以帮助找到一种方法来查找非唯一性,也许会更容易 -> 所以从上面的示例中我只能得到 item[0] 和 item[1]

I got a list<list<string>>

in list[x][0] are records from which I want to choose unique records thus such record wouldn't be in any other list[x][0], when I choose it, i'd like whole row list[x] to be chosen. I haven't found the appropriate exapmple for this in Linq, please help :(

EDIT

When Jon Skeet asks me to clarify, I can't deny ;-)

list<list<string>>

contains list of string table . Each of the string "table" contains several keys list[x][several_items] and I want to get unique records from list-> meaning FIRST item in that "table".

Thus:

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

-> unique would mean that I can derive rows item[3] and item[4] as unique. because first occurence of number/string is important.

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

First element of each list is important to determine uniqueness. Maybe it'd be easier if someone can help to find a way to find non-unique -> so from the above example the list I'd get only item[0] and item[1]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深爱不及久伴 2024-07-23 17:34:18

编辑:我已经更新了底部的 UniqueBy 实现,以显着提高效率,并且仅迭代源一次。

如果我正确理解了你(问题很不清楚 - 如果你能提供一个例子,这真的很有帮助)这就是你想要的:

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;
    }
}

编辑:好的,如果你只关心列表的第一个元素的唯一性,我们需要稍微改变一下:

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;
    }
}

你可以这样称呼它:

list.UniqueBy(row => row[0])

EDIT: I've updated the UniqueBy implementation at the bottom to be significantly more efficient, and only iterate through the source once.

If I've understood you correctly (the question is pretty unclear - it would really help if you could provide 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: Okay, if you only care about the first element of the list for uniqueness, we need to change it somewhat:

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'd call it with:

list.UniqueBy(row => row[0])
千鲤 2024-07-23 17:34:18

也许是这样的?

鉴于您的澄清,我现在相当确定这对您有用:)

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 现在包含上面的“d”和“e”条目。

Something like this, perhaps?

I'm now fairly sure this would 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" entries from above.

暖伴 2024-07-23 17:34:18

这是您需要的代码。 仅选择不同的值对我来说非常有效。

//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();

Here is the code you need. It works perfectly for me to select ONLY distinct 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();
飘然心甜 2024-07-23 17:34:18

这是给您的一些 Linq。

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();

Here's 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();
ペ泪落弦音 2024-07-23 17:34:18

我将继续将这一点添加到战斗中。

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);
                }
            }
        }
    }
}

I'll just go ahead and add this one 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);
                }
            }
        }
    }
}
只有一腔孤勇 2024-07-23 17:34:18

您可以维护一个列表和一个索引/字典

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

当您添加将项目添加到值中,您还可以将列表添加到索引中,并以字符串作为索引。

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

然后,您可以通过以下方式获得正确的列表:

List<string> list = index[searchFor]

在构建索引时,您会损失一些(最小的)性能和内存,但在检索数据时,您会获得很多性能和内存。

如果字符串不唯一,您还可以存储一个 List> 在 字典/index 中,允许每个索引键有多个结果。

抱歉,没有 Linq,这看起来不太酷,但是您可以快速查找,而且恕我直言,查找代码更清晰。

You could maintain a list and an index/dictionary:

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

When you add an item to values, you also add the List to the index with the string as index.

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

Then you can get the correct list by:

List<string> list = index[searchFor]

You loose some (minimal) performance and memory when building the index, but you gain a lot when retrieving the data.

If the string is not unique, you could also store a List> in the dictionary/index, to allow multiple results per index key.

Sorry no Linq, this doesn't look that cool, but you have a fast lookup, and IMHO the lookup code is more clear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文