1

私はこのリストを持っています:

List<myobject> list= new List<myobject>();

list.Add(new myobject{name="n1",recordNumber=1}); 
list.Add(new myobject{name="n2",recordNumber=2}); 
list.Add(new myobject{name="n3",recordNumber=3});
list.Add(new myobject{name="n4",recordNumber=3});

recordNumberに基づいて個別のオブジェクトを選択する最速の方法を探していますが、同じrecordNumber(ここではrecordNumber = 3)を持つオブジェクトが複数ある場合は、その名前(パラメーターによって提供される名前)に基づいてオブジェクトを選択します。 )。

ありがとう

4

5 に答える 5

2

あなたは本当に次のようなものを求めているようです:

Dictionary<int, List<myobject>> myDataStructure;

これにより、レコード番号ですばやく取得できます。List<myobject>そのディクショナリ キーを持つ に複数のエントリが含まれている場合は、名前を使用して正しいエントリを選択できます。

リストがそれほど長くない場合は、リストをスキャンして recordNumber と名前をチェックするだけの O(n) チェックで十分に高速である可能性があることに注意してください。これは、プログラム内で他のことが起こっているため、リストのルックアップ コストがわかりにくくなる可能性があるためです。検索時間を過度に最適化する前に、その可能性を考慮してください。

于 2012-08-29T02:44:35.190 に答える
2

これを行うLINQの方法は次のとおりです。

Func<IEnumerable<myobject>, string, IEnumerable<myobject>> getDistinct =
    (ms, n) =>
        ms
            .ToLookup(x => x.recordNumber)
            .Select(xs => xs.Skip(1).Any()
                ? xs.Where(x => x.name == n).Take(1)
                : xs)
            .SelectMany(x => x)
            .ToArray();

ランダムに作成された 1,000,000 個のmyobjectリストでこれをテストしたところ、106 ミリ秒で結果が得られました。これは、ほとんどの状況で十分に高速なはずです。

于 2012-08-29T03:18:00.603 に答える
1

何方をお探しですか

class Program
    {
        static void Main(string[] args)
        {
            List<myobject> list = new List<myobject>();

            list.Add(new myobject { name = "n1", recordNumber = 1 });
            list.Add(new myobject { name = "n2", recordNumber = 2 });
            list.Add(new myobject { name = "n3", recordNumber = 3 });
            list.Add(new myobject { name = "n4", recordNumber = 3 });

            //Generates Row Number on the fly
            var withRowNumbers = list 
                    .Select((x, index) => new 
                            {
                                Name = x.name,
                                RecordNumber = x.recordNumber,
                                RowNumber = index + 1
                            }).ToList();

            //Generates Row Number with Partition by clause
            var withRowNumbersPartitionBy = withRowNumbers
                    .OrderBy(x => x.RowNumber)
                    .GroupBy(x => x.RecordNumber)
                    .Select(g => new { g, count = g.Count() })
                    .SelectMany(t => t.g.Select(b => b)
                    .Zip(Enumerable.Range(1, t.count), (j, i) => new { Rn = i, j.RecordNumber, j.Name}))
                    .Where(i=>i.Rn == 1)
                    .ToList();
            //print the result
            withRowNumbersPartitionBy.ToList().ForEach(i => Console.WriteLine("Name =  {0}   RecordNumber = {1}", i.Name, i.RecordNumber));

            Console.ReadKey();
        }
    }

    class myobject
    {
        public int recordNumber { get; set; }
        public string name { get; set; }
    }

結果:

Name =  n1   RecordNumber = 1
Name =  n2   RecordNumber = 2
Name =  n3   RecordNumber = 3
于 2012-08-29T03:14:52.140 に答える
0

これを行う方法を探していますか?

List<myobject> list= new List<myobject>();

list.Add(new myobject{name="n1",recordNumber=1}); 
list.Add(new myobject{name="n2",recordNumber=2}); 
list.Add(new myobject{name="n3",recordNumber=3});
list.Add(new myobject{name="n4",recordNumber=3});

public myobject Find(int recordNumber, string name)
{
    var matches = list.Where(l => l.recordNumber == recordNumber);

    if (matches.Count() == 1)
        return matches.Single();

    else return matches.Single(m => m.name == name);
}

もちろん、複数の一致がある場合、または一致しない場合、これは壊れます。独自のエッジ ケースとエラー処理を作成する必要があります。

于 2012-08-29T02:51:01.797 に答える
0

If the name and recordNumber combination is guaranteed to be unique then you can always use Hashset.

You can then use RecordNumber and Name to generate the HashCode by using a method described here.

class myobject 
{

     //override GetHashCode
     public override int GetHashCode()
     {
        unchecked // Overflow is fine, just wrap
        {
           int hash = 17;
           // Suitable nullity checks etc, of course :)
           hash = hash * 23 + recordNumber.GetHashCode();
           hash = hash * 23 + name.GetHashCode();
           return hash;
         }
     }
     //override Equals      
}
于 2012-08-29T03:55:11.237 に答える