#c# #.net #linq
#c# #.net #linq
Вопрос:
public class Name {
public string language { get; set; }
public string text { get; set; }
}
public class ValueItem {
public string id { get; set; }
public List<Name> names { get; set; }
public object syn { get; set; }
public List<string> prop { get; set; }
public string dataType { get; set; }
}
public class Source {
public string id { get; set; }
public string name { get; set; }
}
public class Result {
public List<ValueItem> valueItems { get; set; }
public Source source { get; set; }
}
public class Data {
public List<Result> result { get; set; }
public int totalpages { get; set; }
public int totalrecords { get; set; }
public int pagesize { get; set; }
public int pagenumber { get; set; }
}
у меня есть структура модели, подобная приведенной выше, я пытаюсь удалить объект с именем на основе текста. Если строка, которую я передаю, присутствует в Name.text, этот конкретный объект name должен быть удален. Как добиться этого с помощью linq или lambda.
я пытался : var data1= data.Result.Where(x=>x.ValueItems.Where(a=>a.Names.SelectMany(b=>!str.Contains(b.Text)))).ToList()
Комментарии:
1. Попробуйте это (я думаю, это должно сработать):
var data1= data.Result.Where(x=>x.ValueItems.Where(a=>a.Names.Any(b=>b.Text.Contains(str)))).ToList();
. Вы сказали, что если текст содержит строку, а не наоборот, что вы и делаете. Отрицание также не соответствует тому, что вы говорите, что хотите в результате.2. Просто чтобы убедиться: 1) Запрос linq не удалит никаких объектов, он вернет новый список с отфильтрованными результатами и 2) Если пробелы неуместны, вы можете захотеть обрезать входную строку перед использованием ее в запросе.
3. Если условие соответствует, следует ли удалять весь
result
объект или толькоname
? используемый вами linq фильтруетresult
объект, а неnames
. Не могли бы вы, пожалуйста, привести какой-нибудь пример?
Ответ №1:
Вы можете добиться желаемого, вернув отфильтрованную версию исходных данных:
data.result = data.result.Select(x => new Result
{
source = x.source,
valueItems = x.valueItems.Select(a =>
new ValueItem
{
prop = a.prop,
dataType = a.dataType,
id = a.id,
syn = a.syn,
names = a.names
.Where(i => i.text != stringToRemove)
.ToList()
}).ToList()
}).ToList();
Однако альтернативной версией (без использования LINQ) достижения того же самого может быть:
foreach (var result in data.result)
{
foreach (var resultValueItem in result.valueItems)
{
resultValueItem.names.RemoveAll(i => i.text == stringToRemove);
}
}
Примечание: стоит упомянуть, что второй вариант более эффективен с точки зрения производительности, поскольку здесь не происходит выделения памяти.
Несколько замечаний к вышеупомянутым решениям:
- Если вам не нужно точное совпадение, но возможны сценарии, когда ваш текст может быть частью строки большего размера, используйте String.Содержит вместо приведенного выше сравнения.
- Рассмотрите возможность применения одной из строк: .Уменьшить, строку.ToLowerInvariant, String.Обработчик, String.Жестковариантные методы для обоих
stringToRemove
иi.text
на случай, если вы хотите сравнение без учета регистра.