3

私は得たlist<list<string>>

inlist[x][0]は、一意のレコードを選択したいレコードであるため、そのようなレコードは他のレコードにはありませんlist[x][0]、それを選択すると、行全体list[x]が選択されます。Linq でこれに適した例が見つかりませんでした。助けてください :(

編集

ジョン・スキートが私に明確にするように頼んだとき、私は否定できません;-)

list<list<string>>

文字列テーブルのリストを含みます。文字列「テーブル」のそれぞれにはいくつかのキーが含まれておりlist[x][several_items]、リストから一意のレコードを取得したい->その「テーブル」の最初のアイテムを意味します。

したがって:

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

-> unique は、行を一意として導出できることを意味しますitem[3] and item[4]。数値/文字列の最初の出現が重要であるためです。

2 つ以上のレコード/行 (item[x] of which first item (item[x][0])リストに複数存在する場合、一意ではありません。

各リストの最初の要素は、一意性を判断するために重要です。たぶん、誰かが一意でないものを見つける方法を見つけるのを手伝ってくれればもっと簡単でしょう - >上の例から、リストは item[0] と item[1] だけを取得します

4

6 に答える 6

10

編集:UniqueBy下部の実装を大幅に効率的に更新し、ソースを 1 回だけ反復します。

私があなたを正しく理解していれば(質問はかなり不明確です-例を提供していただけると本当に助かります)、これがあなたが望むものです:

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])
于 2009-04-07T07:28:22.540 に答える
2

必要なコードは次のとおりです。個別の値のみを選択することは私にとって完璧に機能します。

//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();
于 2010-10-13T14:15:26.667 に答える
2

もしかして、こういうこと?

あなたの明確化を考えると、これはあなたにとってうまくいくと確信しています:)

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」エントリが含まれるようになりました。

于 2009-04-07T07:37:00.100 に答える
1

ここにあなたのための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();
于 2009-04-07T12:46:22.010 に答える
0

リストとインデックス/辞書を維持できます:

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

項目を値に追加すると、文字列をインデックスとしてリストもインデックスに追加されます。

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

次に、次の方法で正しいリストを取得できます。

List<string> list = index[searchFor]

インデックスを構築するときはパフォーマンスとメモリがいくらか (最小限) 失われますが、データを取得するときは多くのことが得られます。

文字列が一意でない場合は、List> をディクショナリ/index に格納して、インデックス キーごとに複数の結果を許可することもできます。

申し訳ありませんが、これはそれほどクールに見えませんが、ルックアップは高速であり、ルックアップコードはより明確です。

于 2009-04-07T07:38:48.287 に答える
0

先に進んで、これを争いに追加します。

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);
                }
            }
        }
    }
}
于 2009-04-07T07:50:09.007 に答える