2010-11-13 32 views
10

我有一個List<bool>。我需要獲得項目值= true的前n個項目的索引。Lambda表達式有條件地獲取列表項的索引

例如,下面的列表項(布爾)

10011001000 

TopTrueIndexes(3) = The first 3 indexes where bits are true are 0, 3, 4 
TopTrueIndexes(4) = The first 4 indexes where bits are true are 0, 3, 4, 7 

我怎麼能寫這樣的拉姆達?

回答

30

好吧,假設你有一些易於識別的情況下,你可以做這樣的事情,這會爲任何工作IEnumerable<T>

var query = source.Select((value, index) => new { value, index }) 
        .Where(x => x.value => Condition(value)) 
        .Select(x => x.index) 
        .Take(n); 

(顯然在的相應位填Where子句。如果它只是一個List<bool>它可能只是x => x.value。)

重要的是你使用的重載獲得指數/值對Where前,然後又Select到的Where後得到的只是指標...並使用Take只得到第一個n結果。

+4

不錯,我不知道你可以做Select((val,ind)=> ...)。 +1 – Alxandr 2010-11-13 21:15:56

+0

@Alxandr:這可以通過直接調用Select方法來完成,但不能通過查詢表達式來完成。 – 2010-11-13 21:18:53

+0

@Jon。非常好,謝謝。 – Jimmy 2010-11-13 21:19:35

0

這應該可以做到這一點。

IEnumerable<bool> GetItemsInList(IEnumerable<bool> list, int count) { 
    int ind = 0; 
    return list.Select(itm => new {i = ind++, v = itm}).Where(itm => itm.v).Take(count).Select(itm => itm.i); 
} 
+0

這隻會給真實的,真的,真的,真實的...'計數'次。它不給*索引*。 – 2010-11-13 21:13:49

+0

對不起,也看到了,並修復了它。 – Alxandr 2010-11-13 21:15:02

2

有一個Select的重載,其中lambda獲取兩個參數:索引和元素。所以你可以把這些指標放在值爲真的地方,爲你不想要的指標提供一個哨兵(這裏是-1)。然後過濾出哨兵,並採取多少你想要的:

bool[] bools = ...; 
var indices = bools.Select((val, ix) => val ? ix : -1).Where(i => i >= 0).Take(n); 
+0

你的lambda中有相反順序的索引和元素,這會混淆人們(讓我困惑)。它應該是'Select((val,ix)...'。 – Mud 2015-06-30 04:40:47