удалить строку из списка, содержащегося в списке классов

#c# #loops #reference

#c# #циклы #ссылка

Вопрос:

У меня есть приведенный ниже список:

 List<MyClass> problemList = new List<MyClass>;
  

класс структурирован следующим образом:

 public class MyClass
{
    public int UserId { get; set; }
    public string FullName { get; set; }
    public string Role { get; set; }
    public List<string> ForumList { get; set; }

    public MyClass()
    {
        ForumList = new List<string>();
    }
}
  

У меня есть другой список, который отправляется в качестве параметра:

 List<string> fForums = new List<string>;
  

Мне нужно иметь возможность просмотреть мой список проблем.ForumList и удалить все названия форумов, которые
НЕ в списке fForums.

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

 foreach (var i in problemList)
    foreach (var n in i.ForumList)
        if (!fForums.Contains(n))
                     i.ForumModList.Remove(n);
  

Кто-нибудь знает, как заставить это работать?
Заранее спасибо!

Комментарии:

1. Я думаю, что изменение моего внешнего цикла на for может сработать. Придется попробовать в понедельник утром, спасибо!

Ответ №1:

Наиболее очевидный способ — создать пересечение обоих списков форума и присвоить его свойству:

 problemList.ForEach(mc => mc.ForumList = mc.ForumList.Intersect(fForums).ToList());
  

Для следующего примера:

 List<MyClass> problemList = new List<MyClass>
{
    new MyClass {ForumList = new List<string>{"aaa", "bbb", "ccc"}},
    new MyClass {ForumList = new List<string>{"aaa", "bbb"}},
    new MyClass {ForumList = new List<string>{"xxx", "yyy"}},
};

List<string> fForums = new List<string> {"aaa", "bbb"};

problemList.ForEach(mc => mc.ForumList = mc.ForumList.Intersect(fForums).ToList());
  

Элементы в списке задач будут иметь следующие значения для своего списка форумов:

1: "aaa","bbb"

2: "aaa","bbb"

3: <empty>

Ответ №2:

Самым простым способом было бы создавать новую копию вашего forumList на каждой итерации. Вот так:

 foreach (var i in problemList)
    List fList = new ArrayList(i.ForumList);
    foreach (var n in fList)
        if (!fForums.Contains(n))
                     i.ForumModList.Remove(n);
  

Таким образом, вы редактируете не список, который вы повторяете, а его копию.

Комментарии:

1. Будет ли это копией или ссылкой?. Придется попробовать в понедельник утром, когда я вернусь. Спасибо за помощь

2. Это создаст копию.

Ответ №3:

Если я правильно понимаю, вы хотите удалить из списка задач ForumList все записи, которые не найдены. Вы могли бы сделать следующее:

 problemList.ForumList.RemoveAll(f => !fForums.Contains(f));
  

Протестировано с:

 MyClass problemList = new MyClass();
problemList.ForumList.Add("A");
problemList.ForumList.Add("B");
problemList.ForumList.Add("C");
problemList.ForumList.Add("D");
problemList.ForumList.Add("E");

List<string> fForums = new List<string>();
fForums.Add("C");
fForums.Add("D");

problemList.ForumList.RemoveAll(f => !fForums.Contains(f));
  

problemList.ForumList осталось два элемента, C и D .

Это то, что вы искали?

Комментарии:

1. Отлично!. Придется попробовать в понедельник утром, когда я вернусь к работе. Мне нравится ваше решение, потому что оно компактное. Пытался использовать .where .select .remove .contains, но не смог подобрать правильные комбинации.

2. @chris Я не был уверен, правильно ли я интерпретировал вопрос 🙂 Надеюсь, у вас это сработает.

3. Это не сработало, потому что у меня есть список ptoblemList. Ваше решение будет работать только с одним объектом класса.

4. @chris ты можешь просто problemList.ForEach а затем сделать то, что сделал я … это просто еще один слой, и поэтому он должен работать просто отлично. Я думаю, что мое решение более эффективно, поскольку оно редактирует текущий список вместо создания новой версии и переназначения ее.

Ответ №4:

Я не уверен, какую версию вы хотите, поэтому я оставлю две версии:

Это приведет к удалению из списка форумов каждого problemList , который соответствует элементу в fForumn.

 foreach (var problemItem in problemList)
{
    problemItem.ForumList = problemItem.ForumList
        .Except(fForums);
}
  

В этой версии вам нужно просмотреть каждый problemList элемент. Для этого элемента проверьте, соответствует ли какой-либо из ForumnList элементов элементу в fForums . Если есть какие-либо совпадающие, исключите problemList элемент.

 var filteredList = problemList
    .Where(x => !x.ForumList.Intersect(fForums).Any())
    .ToList();
  

Intersect вернет элементы, которые находятся в обоих x.ForumList и fForums . Поэтому, если есть Any такое совпадение, его следует исключить.