Какой самый элегантный способ обновить элемент в одном списке из другого списка в C #? - PullRequest
2 голосов
/ 11 января 2012

У меня есть 2 коллекции, и у меня есть следующий код, чтобы пройтись по одной коллекции и посмотреть, существует ли она в другой коллекции.Если он существует, обновите свойство этого элемента.

        foreach (var favorite in myFavoriteBooks)
        {
            var book = allBooks.Where(r => r.Name == favorite.Name).FirstOrDefault();

            if (book != null)
            {
                book.IsFavorite = true;
            }
        }

Есть ли более элегантный или более быстрый способ выполнения этого кода выше?

Ответы [ 4 ]

5 голосов
/ 11 января 2012

Для этого вы можете использовать Join в синтаксисе метода расширения или в синтаксисе LINQ:

Метод расширения:

foreach(var favorite in myFavoriteBooks.Join(allBooks, 
                                             f => f.Name, 
                                             a => a.Name, 
                                            (f, a) => a))
{
    a.IsFavorite = true;
}

LINQ:

var favorites = from f in myFavoriteBooks
                join a in allBooks on f.Name equals a.Name
                select a

foreach(var favorite in favorites)
{
    favorite.IsFavorite = true;
}

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

3 голосов
/ 11 января 2012

Вы можете легко найти книги в одной коллекции, которые соответствуют другой коллекции с Any

var booksInCommon = allBooks.Where(b => myFavoriteBooks.Any(bi => bi.Name == b.Name));
foreach(book b in booksInCommon)
   b.IsFavorite = true;

Или, если не возражаете против "хитрого" кода

allBooks.Where(b => myFavoriteBooks.Any(bi => bi.Name == b.Name)).ToList()
    .ForEach(b => b.IsFavorite = true);

EDIT

Как указывает Адам Робинсон, это алгоритм O (N 2 ), поэтому избегайте его, если у вас есть тысячи книг в обеих ваших коллекциях и выберите его ответ Join.

1 голос
/ 11 января 2012

Если коллекции книг хранились в словарях с ключом Имени, то это становится простой и очень эффективной операцией:

        var myFavoriteBooks = new System.Collections.Generic.Dictionary<string, book>();
        var allBooks = new System.Collections.Generic.Dictionary<string, book>();

        foreach (var bookName in myFavoriteBooks.Keys)
        {
            if (allBooks.ContainsKey(bookName))
            {
                allBooks[bookName].IsFavorite = true;
            }
        }
0 голосов
/ 11 января 2012
var favTitles = new HashSet<string>(favorite.Select(f => f.Name));
//favTitles now a hash-based O(1) name lookup.
foreach(var book in allBooks.Where(b => favTitles.Contains(b.Name)))
  book.IsFavorite = true;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...