2015-04-23 163 views
0

有沒有辦法用LINQ來選擇具有快捷標準的特定數字。 喜歡這個: 我有1 to 10000的號碼。 我的標準是(4012..4190|4229)4012 to 4190和數量4229間意取號:選擇時間間隔linq

static int[] test(string criteria) 
    { 
     // criteria is 4012..4190|4229 
     // select numbers from lab where criteria is met 
     int[] lab = Enumerable.Range(0, 10000).ToArray(); 

     return lab; 
    } 
+3

你已經做了什麼努力? – Andrey

回答

3

如果您criteria始終是一個string,你需要一些方法來分析它,Func<int, bool,但它不是LINQ特定。到底你需要這樣的事:

Func<int, bool> predicate = Parse(criteria); 
return lab.Where(predicate).ToArray(); 

其中非常基本實現Parse可能如下:

public static Func<int, bool> Parse(string criteria) 
{ 
    var alternatives = criteria 
     .Split('|') 
     .Select<string, Func<int, bool>>(
      token => 
      { 
       if (token.Contains("..")) 
       { 
        var between = token.Split(new[] {".."}, StringSplitOptions.RemoveEmptyEntries); 
        int lo = int.Parse(between[0]); 
        int hi = int.Parse(between[1]); 
        return x => lo <= x && x <= hi; 
       } 
       else 
       { 
        int exact = int.Parse(token); 
        return x => x == exact; 
       } 
      }) 
     .ToArray(); 

    return x => alternatives.Any(alt => alt(x)); 
} 
+0

這是很棒的東西!奇蹟般有效。非常感謝 – Gmorken

3

這應該足以爲你的情況:

return lab.Where((int1) => (int1 >= 4012 && int1 <= 4190) || int1 == 4229).ToArray(); 

而且解析您的標準的快速方法是使用正則表達式:

Regex r = new Regex(@"\d+"); 
MatchCollection m = r.Matches(criteria); 
int start = int.Parse(m[0].Value); 
int end = int.Parse(m[1].Value); 
int specific = int.Parse(m[2].Value); 
return lab.Where((int1) => (int1 >= start && int1 <= end) || int1 == specific).ToArray(); 
1

可以連接兩個序列

int[] lab = Enumerable.Range(4012, 4190-4012).Concat(Enumerable.Range(4229,1)).ToArray(); 

更新:

你需要解析第一個進入的標準

static int[] test(string criteria) 
    { 
     // criteria is 4012..4190|4229 
     // select numbers from lab where criteria is met 

     // assume you parsed your criteria to 2 dimentional array 
     // I used count for second part for convience 
     int[][] criteriaArray = { new int[]{ 4012, 50 }, new int[]{ 4229, 1 } }; 

     var seq = Enumerable.Range(criteriaArray[0][0], criteriaArray[0][1]); 

     for (int i = 1; i < criteriaArray.Length; i++) 
     { 
      int start = criteriaArray[i][0]; 
      int count = criteriaArray[i][1]; 
      seq = seq.Concat(Enumerable.Range(start, count)); 
     } 


     return seq.ToArray(); 
    } 
+0

順便說一句,你需要解析你的標準,並取代各自的數字 – Orifjon

+0

偉大的工作,但問題是這樣的標準可以看起來像這樣不同: 4370 | 7010..7299 | 7331..7575 | 7691。 .7698 4480 | 7310 | 7610..7690 等等...如何解決這個問題?我如何解析標準? – Gmorken

+0

如果你解析條件數字對數組(開始,計數)或(開始,結束),你可以連接你的序列在循環 – Orifjon

0

,你可以: Flatten[{Range[4012, 4190], 4229}]

並以某種方式這也可以工作4012..4190|4229,但答案正是 - 從4012到4190和項目4229的項目列表。

Lambda只是模仿純粹的功能。但是,除非你有免費的wolfram內核,否則使用這種方法可能不是最具成本效益的。但是,您不需要編寫樣板代碼。