2016-08-22 26 views
1

我想用數組的索引創建一個數組。讓我們假設我有一個這樣的數組:從源數組中選擇指定的索引範圍

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 

而結果我從查詢得到的樣子:

enter image description here

這意味着地方13, 4LengthUnit = 2)和7正忙(已經採取)。所以,陣列現在看起來像:

| T | 2 | T | T | 5 | 6 | T | 8 | 9 | 10 | 

其中,T代表採取。

如何創建使用結果從查詢整數的兩排它會是什麼樣子:

int[] taken = { 1, 3, 4, 7 }; 
int[] notTaken = { 2, 5, 6, 8, 9, 10 }; 
+1

循環查詢結果並Skip()和Take()相應的索引?你有什麼嘗試? – CodeCaster

+0

開始單位有'1,3,7'howz'4'被拍攝? – yogi

+0

@ yogi這個問題沒有解釋,但是給定3的長度單位是2,我假設OP想要從3開始取2條記錄。 – CodeCaster

回答

5

Enumerable.Range證明是有用的在這種情況下:

Dictionary<int, int> startAndLength = new Dictionary<int, int>() 
             { { 1, 1 }, { 3, 2 }, { 7, 1 } }; 

int[] taken = startAndLength 
       .SelectMany(kvp => Enumerable.Range(kvp.Key, kvp.Value)).ToArray(); 

int[] notTaken = Enumerable.Range(0, 10).Except(taken).ToArray(); 

開始產生一組的開始和長度,然後DETE使用Enumerable.Range拍攝的物品。然後再次使用Enumerable.Range確定項目而不是

2

使用Enumerable.Range創造你想要的物品的集合。然後使用Except來獲得其他。

List<int> values = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

List<Tuple<int, int>> ranges = new List<Tuple<int, int>> 
{ 
    new Tuple<int, int>(1,1), 
    new Tuple<int, int>(3,2), 
    new Tuple<int, int>(7,1), 
}; 

var t = ranges.SelectMany(range => Enumerable.Range(range.Item1, range.Item2)).ToList(); 

// Here I decide to use Intersect instead of just having t for the case 
// where you requested a range that doesn't exist 
var taken = values.Intersect(t).ToArray(); 
var notTaken = values.Except(taken).ToList(); 

在您需要的值的情況下,他們不是連續比如上例中則相反:創建所有期望的索引的集合,然後獲取這些指標的所有項目:

var indexes = ranges.SelectMany(range => Enumerable.Range(range.Item1, range.Item2)).Select(item => item - 1).ToList(); 

var taken = values.Where((item, index) => indexes.Contains(index)).ToList(); 
var notTaken = values.Where((item, index) => !indexes.Contains(index)).ToList(); 
1

一點點的LINQ將讓你很長的路要走:

public class QueryResult 
{ 
    public int StartUnit { get; set; } 
    public int LengthUnit { get; set; } 
} 

var input = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

var queryResult = new QueryResult[] 
{ 
    new QueryResult { StartUnit = 1, LengthUnit = 1 }, 
    new QueryResult { StartUnit = 3, LengthUnit = 2 }, 
    new QueryResult { StartUnit = 7, LengthUnit = 1 }, 
}; 

var taken = new List<int>(); 

taken.AddRange(queryResult.SelectMany(q => (input.Skip(q.StartUnit - 1).Take(q.LengthUnit)))); 

Console.WriteLine("Taken: {0}", string.Join(",", taken)); 

var notTaken = input.Except(taken); 

Console.WriteLine("Not taken: {0}", string.Join(",", notTaken)); 

使用SelectMany()Skip()Take(),您可以選擇您要包括的範圍。使用Except()即可獲取未拍下的物品。

請注意,這會執行可怕的,因爲它迭代收集方式太多次。它還假定StartUnit實際上表示輸入集合中的一個(索引+ 1),而不是一個值。

如果你實際上並不想看看輸入數組和值總是連續的(輸入即無孔),可以使用Enumerable.Range()生成請求範圍:

taken.AddRange(queryResult.SelectMany(q => Enumerable.Range(q.StartUnit, q.LengthUnit))); 

並且生成全範圍爲Except(),以排除:

var notTaken = Enumerable.Range(1, 10).Except(taken); 

當然,如果你想輸出實際上是數組,做一個呼叫ToArray()在這裏和那裏。

+0

@Tim,但它假設輸入始終是連續的。 – CodeCaster