2010-06-03 107 views
4

我有一個對象的集合,每個對象都有一個int Frame屬性。給定一個int,我想找到最接近Frame的集合中的對象。用Linq搜索

下面是我在做什麼至今:

public static void Search(int frameNumber) 
{ 
    var differences = (from rec in _records 
         select new { FrameDiff = Math.Abs(rec.Frame - frameNumber), Record = rec }).OrderBy(x => x.FrameDiff); 

    var closestRecord = differences.FirstOrDefault().Record; 

    //continue work... 
} 

這是偉大的,一切,除了有我收集的20萬個項目,我非常頻繁調用此方法。有沒有一種相對容易,更有效的方法來做到這一點?

+1

這是LINQ到對象或LINQ to SQL的集合嗎? – Jimmy 2010-06-03 15:58:13

+0

「我有一個對象集合」,這個問題的第一句話。 ;) – jsmith 2010-06-03 16:02:31

回答

5
var closestRecord = _records.MinBy(rec => Math.Abs(rec.Frame - frameNumber)); 

使用來自MoreLINQ的MinBy。

3

你可能想嘗試什麼是幀存儲在由真實分類Frame一個數據結構。然後,您可以在需要查找與給定frameNumber最接近的一個時進行二分搜索。

+0

也許查看SortedList集合作爲您的數據結構。 – Reddog 2010-06-03 16:01:42

+0

是不是在linq做到這一點?這將是怎樣的linq?代碼示例? – jsmith 2010-06-03 16:03:52

+0

我會沒有使用linq的解決方案。我只是在尋找「簡單」。 – Phil 2010-06-03 16:08:37

0

您可以將報表合併到一個翼:

var closestRecord = (from rec in _records 
        select new { FrameDiff = Math.Abs(rec.Frame - frameNumber), 
        Record = rec }).OrderBy(x => x.FrameDiff).FirstOrDefault().Record; 
+2

我相信他的問題是這樣的(實際上不需要)需要很長時間。 – Ghostrider 2010-06-03 16:00:51

0

也許你能在5分你的大ITEMLIST - 由他們Framediff什麼訂購10架較小的列表?

這種搜索是更快,如果你知道在哪個列出你需要搜索

1

我不知道,我會使用LINQ這一點,至少不會與排序依據。

static Record FindClosestRecord(IEnumerable<Record> records, int number) 
{ 
    Record closest = null; 
    int leastDifference = int.MaxValue; 

    foreach (Record record in records) 
    { 
     int difference = Math.Abs(number - record.Frame); 
     if (difference == 0) 
     { 
      return record; // exact match, return early 
     } 
     else if (difference < leastDifference) 
     { 
      leastDifference = difference; 
      closest = record; 
     } 
    } 

    return closest; 
} 
+0

這很像是MoreLINQ的'MinBy'方法 - 正如dtb的答案中所建議的那樣 - 起作用。 (雖然'MinBy'不能特別爲早期退出進行精確匹配。) – LukeH 2010-06-03 16:17:14

+0

如果你有一個排序後的集合,你可以有更好的提前退出。此外,如果您使用「for」循環,則可以記住上次使用的索引,並從該處開始搜索,而不是從集合的開始處開始搜索。簡單和快速之間的良好平衡。這是我最終選擇做的,運作良好。 – Phil 2010-06-04 02:56:51