2013-03-01 114 views
8

在C#中,我試圖從列表中獲取隨機索引中的項目。當它被取回時,我希望它被刪除,以便它不能被選中。看起來好像我需要很多操作來做到這一點,是不是有一個功能,我可以簡單地從列表中提取一個項目? RemoveAt(索引)函數是無效的。我希望有一個返回值。從列表中刪除項目並同時獲取項目

我在做什麼:

List<int> numLst = new List<int>(); 
numLst.Add(1); 
numLst.Add(2); 

do 
{ 
    int index = rand.Next(numLst.Count); 
    int extracted = numLst[index]; 
    // do something with extracted value... 
    numLst.removeAt(index); 
} 
while(numLst.Count > 0); 

我想這樣做:

List<int> numLst = new List<int>(); 
numLst.Add(1); 
numLst.Add(2); 

do 
{ 
    int extracted = numLst.removeAndGetItem(rand.Next(numLst.Count)); 
    // do something with this value... 
} 
while(numLst.Count > 0); 

難道這樣的 「removeAndGetItem」 功能存在嗎?

+0

你不得不寫你自己的 - 據我所知,只有Stack或Queue具有內置的這種功能。這需要線程安全嗎? – 2013-03-01 09:13:35

+1

爲什麼不能得到你想要的新變量/列表? – Kaf 2013-03-01 09:14:29

回答

15

不,因爲它違背了純粹的功能禮儀,一種方法有副作用,或者返回一個有用的值(即不只是表示錯誤狀態) - 從來都不是。

如果你想要的功能出現原子,就可以得到獲取名單,這將阻止其他線程訪問列表上的鎖,而要修改它:

public static class Extensions 
{ 
    public static T RemoveAndGet<T>(this IList<T> list, int index) 
    { 
     lock(list) 
     { 
      T value = list[index]; 
      list.RemoveAt(index); 
      return value; 
     } 
    } 
} 
+0

請記住,只有在同時調用RemoveAndGet時,鎖定纔會有所幫助。其他一些函數仍然可以修改列表,並且仍然會出現OutOfBoundsException。如下所述,可以考慮異常處理。 – mateuscb 2013-12-18 16:12:27

+2

關於命令和查詢的第一部分是不正確的,'Add'具有副作用並且在同一個類上返回一個值......它也不總是實用的,例如以Stack爲例,'Pop'有副作用並返回一個值。 (我喜歡命令和查詢的想法,但是這個概念不是在.NET中強制執行的,並不總是你想要的) – 2015-05-17 11:30:53

+0

個人而言,我認爲我的「有用」部分在絕大多數用例中,答案仍適用於從「添加」返回的值。 – RoadieRich 2015-05-17 14:35:22

5
public static class ListExtensions 
{ 
    public static T RemoveAndGetItem<T>(this IList<T> list, int iIndexToRemove} 
    { 
    var item = list[iIndexToRemove]; 
    list.RemoveAt(iIndexToRemove); 
    return item; 
    } 
} 

這些被稱爲extension methods,請致電new List<T>().RemoveAndGetItem(0)

相近的擴展方法考慮

異常與您通過索引處理,檢查索引withing 0和列表在此之前的數。

+0

+1我想這跟帶鎖的其他答案是一樣的。感謝您的異常處理說明。 – Eirik 2013-03-01 09:50:39

+0

@Eirik沒有關於如果將無效索引傳遞給IList上的方法會發生什麼的規範,所以我認爲最好將參數驗證留給列表實現。 對於你所知道的,一個自定義的IList實現可能會**出於任何原因**超出範圍索引。 – RoadieRich 2013-03-01 10:04:52

+0

@RichardLovely這就是我說爲什麼要考慮的確切原因。另外,出於好奇,自定義列表有什麼可能會期望超出範圍的索引? – LukeHennerley 2013-03-01 10:07:49