Как мне выполнить функцию FindAll() в IList<T>?(например.Сортированный список.Значения)
-
03-07-2019 - |
Вопрос
Я работаю над проблемой в C # 2.0 / .NET 2.0, где у меня есть Sortedlist и я хочу выполнить поиск по всем "значениям" (не "ключам") этого SortedList для определенной подстроки и подсчитать, сколько там вхождений.
Это то, что я пытаюсь сделать:
{
Sortedlist<string,string> mySortedList;
// some code that instantiates mySortedList and populates it with data
List<string> myValues = mySortedList.Values; // <== does not work
int namesFound = myValues.FindAll(ByName(someName)).Count;
}
Естественно, это не работает, потому что mySortedList.Values возвращает IList, в то время как "myValues" - это список.Я попытался "кастинговать" IList, чтобы он был принят myValues, но, похоже, это не сработало.
Конечно, я могу перебирать mySortedList.Values в цикле "foreach", но я действительно не хочу этого делать.
У кого-нибудь есть какие-нибудь предложения?
ПРАВКА-1:Хорошо, что ж, похоже, что нет родного способа сделать это легко.Я предполагал, что просто чего-то не хватает, но, видимо, это не так.Так что, я думаю, я просто собираюсь сделать "foreach" над IList.
Всем спасибо за отзыв!Я проголосовал за каждого по 1, потому что считал, что все отзывы были хорошими.Еще раз спасибо!:-)
ПРАВКА-2:Похоже, у CMS есть ответ, который я искал.Единственное предостережение при этом (как указал Qwertie) заключается в том, что существует потенциальное снижение производительности, поскольку оно включает копирование всех значений в другой список и затем поиск по этому списку от начала до конца.Таким образом, для коротких списков этот ответ эффективен.Более длинные списки?что ж, это вам решать...
Решение
С тех пор, как Интерфейс IList орудия труда IEnumerable ( количество ), вы действительно можете получить List<T>
значений, использующих List<T> (IEnumerable) Constructor
:
List<string> myValues = new List<string>(mySortedList.Values);
Другие советы
Вы не можете преобразовать свойство Values в List<string> потому что это не список<string>-- это словарь<TKey, TValue="">.ValueCollection .
Но если вы используете LINQBridge - Линкбридж (для .NET Framework 2.0 с C # 3.0) эта проблема легко решается с помощью LINQ следующим образом:
SortedList<string, string> m = ...;
int namesFound = m.Values.Where(v => v.Contains("substring")).Count();
(если вы все еще работаете на C # 2.0, вы можете использовать Ссылка для бедных вместо этого, с чуть большим объемом работы)
Очень жаль, что вы работаете в .Net 2.0.Это именно то, для чего предназначен LINQ.;)
На самом деле вы не можете этого сделать, поскольку FindAll() является членом List .Вы могли бы создать новый список в mySortedList.Values, но это кажется пустой тратой времени, поскольку новый объект и базовый массив должны быть выделены только для вызова функции.
Я бы просто написал служебную функцию в каком-нибудь классе для списков с именем FindAll(), а затем передал ваш IList и делегировал.
Вы пробовали SortedList
's GetValueList
пока?Это вернет вам IList
ценностей.
static void Main(string[] args)
{
string someName = "two";
SortedList<string, string> mySortedList = new SortedList<string,string>()
{
{"key1", "This is key one"},
{"key2", "This is key two"},
{"key3", "This is key three"},
};
int namesFound = mySortedList.Values.Where(i => i.Contains(someName)).Count();
Console.WriteLine(namesFound);
Console.ReadKey();
}
В Framework 2.0, возможно, можно сделать это:
static void Main(string[] args)
{
string someName = "two";
SortedList<string, string> mySortedList = new SortedList<string,string>()
{
{"key1", "This is key one"},
{"key2", "This is key two"},
{"key3", "This is key three"},
};
int namesFound = FindAll(mySortedList.Values, someName).Count ;
Console.WriteLine(namesFound);
Console.ReadKey();
}
public static IList<String> FindAll(IList<String> items, string item)
{
List<String> result = new List<string>();
foreach (String s in items)
{
if (s.Contains(item))
{
result.Add(s);
}
}
return result;
}
Но это то, чего вы на самом деле не хотели делать.