#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
такое совпадение, его следует исключить.