Как получить часть объекта из списка без Linq? - PullRequest
4 голосов
/ 17 декабря 2008

Я использую C # framework 2.0, и я хотел бы получить некоторые данные из списка? Список является списком <>. Как я могу сделать это без циклов и сравнения вручную для каждого элемента списка <>?

Ответы [ 6 ]

8 голосов
/ 17 декабря 2008

Если я правильно понимаю ваш вопрос, вы можете просто вызвать методы Find() или FindAll(), чтобы вывести элементы данных из списка. Например:

List<string> myList = ..;
List<string> startingWithA = myList.FindAll(delegate(string s) { return s.StartsWith("A"); });
4 голосов
/ 17 декабря 2008

Вы можете попробовать Предикат. Вот код, который я написал, чтобы проиллюстрировать это. Конечно, как вы можете видеть в этом примере, вы можете переместить Предикат за пределы вызывающего класса и иметь контроль над ним. Это полезно, если вам нужно иметь больше возможностей с ним. Внутри предиката вы можете проводить множество сравнений со всеми свойствами / функциями вашего объекта.

   static void Main()
    {
        List<SimpleObject> list = new List<SimpleObject>();
        list.Add(new SimpleObject(1,"Jon"));
        list.Add(new SimpleObject( 2,  "Mr Skeet" ));
        list.Add(new SimpleObject( 3,"Miss Skeet" ));
        Predicate<SimpleObject> yourFilterCriteria = delegate(SimpleObject simpleObject)
        {
            return simpleObject.Name.Contains("Skeet");
        };
        list = list.FindAll(yourFilterCriteria);//Get only name that has Skeet : Here is the magic
        foreach (SimpleObject o in list)
        {
            Console.WriteLine(o);
        }
        Console.Read();
    }
    public class SimpleObject
    {
        public int Id;
        public string Name;

        public SimpleObject(int id, string name)
        {
            this.Id=id;
            this.Name=name;
        }

        public override string ToString()
        {
            return string.Format("{0} : {1}",Id, Name);
        }
    }
2 голосов
/ 17 декабря 2008

Без LINQ, ваша основная опция - делать циклы и сравнивать каждый элемент списка. Хотя есть несколько способов, которые могут вам помочь.

List<T>.FindAll() принимает делегата Predicate и возвращает все элементы, соответствующие условию. List<T>.CopyTo() и List<T>.GetRange() позволяют вам извлечь диапазон элементов. Кроме этого, вы действительно не можете сделать ничего особенного в выборе за пределами LINQ.

1 голос
/ 17 декабря 2008

Правда в том, что даже если вы в конечном итоге используете Predicates через Find или FindAll, все, что он делает внутренне, - это циклический просмотр списка и запуск Predicate для проверки на совпадение. По производительности вы ничего не получаете, но это определенно влияет на аккуратность кода.

0 голосов
/ 17 декабря 2008

Я думаю, что большинство из приведенных выше ответов просто предоставляют альтернативные способы сделать именно то, что вы пытаетесь избежать. Учитывая структуру данных, независимо от того, какую реализацию вы выберете, вам / ей придется сравнивать каждый элемент и выбирать те, которые соответствуют.

В зависимости от ваших критериев соответствия, SortedList может помочь вам избежать поиска по всему списку для каждого запроса. Если ваш список содержит объекты, которые вы создали, переопределение GetHashCode и Equals поможет вам.

Если подходящие критерии достаточно сложны, вам может понадобиться другая структура данных, например trie для строк.

0 голосов
/ 17 декабря 2008

К сожалению, структура данных List требует итерации для поиска данных (обратите внимание, что приведенные выше методы FindAll будут повторять вашу коллекцию под покровом - на всякий случай, если вы пытались избежать этого любой ценой), если только вы не знаете индекс этих данных тогда вы можете сделать это:

List<String> list = new List<String>();
list.Add("andrew");
list.Add("nicole");

String value = list[1]; // returns "nicole"
...