我有一个这个清单:
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),我想在其名称上选择对象。(名称)由paramater提供)
感谢
答案 0 :(得分:2)
看起来你真的喜欢这样的事情:
Dictionary<int, List<myobject>> myDataStructure;
这允许您通过记录号快速检索。如果带有该词典键的List<myobject>
包含多个条目,则可以使用该名称选择正确的名称。
请注意,如果您的列表不是非常长,那么只扫描列表检查recordNumber和名称的O(n)检查可能足够快,在某种意义上,其他事情发生在您的程序可能会模糊列表查找成本。在过度优化查找时间之前考虑这种可能性。
答案 1 :(得分: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
列表测试了它,它产生的结果是106ms。对于大多数情况来说,这应该足够快。
答案 2 :(得分: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
答案 3 :(得分: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);
}
这将 - 当然 - 如果有多个匹配或零匹配则中断。您需要编写自己的边缘案例和错误处理!
答案 4 :(得分:0)
如果name和recordNumber组合保证唯一,那么您始终可以使用Hashset。
然后,您可以使用RecordNumber和Name通过使用here描述的方法生成HashCode。
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
}