Я ищу способ найти элементы в List<>, которых нет в строковом значении. У меня есть список<> элементов, как показано ниже:
List<DoorDetails> ListDoorData = new List<DoorDetails>();
DoorDetails dm = new DoorDetails();
dm.door_id = 1;
dm.brand = "BM";
dm.buying_group = "Silly USA";
dm.setting_name = "Settings1";
dm.datamodel = 13;
dm.tracking_weeks = 1;
DoorDetails dm1 = new DoorDetails();
dm1.door_id = 2;
dm1.brand = "NB";
dm1.buying_group = "John USA";
dm1.setting_name = "Settings2";
dm1.datamodel = 16;
dm1.tracking_weeks = 14;
DoorDetails dm11 = new DoorDetails();
dm11.door_id = 3; ;
dm11.brand = "JA";
dm11.buying_group = "Mathew UK";
dm11.setting_name = "Settings3";
dm11.datamodel = 17;
dm11.tracking_weeks = 45;
ListDoorData.Add(dm);
ListDoorData.Add(dm1);
ListDoorData.Add(dm11);
У меня есть строка, имеющая значение, подобное показанному ниже:
string filterstr = "NB|JA";
Я хочу получить «марку» всех элементов, которых нет в «filterstr». Это означает, что ниже находится объект, свойство «бренд» которого не является «NB» и «JA»,
DoorDetails dm = new DoorDetails();
dm.door_id = 1;
dm.brand = "BM";
dm.buying_group = "Silly USA";
dm.setting_name = "Settings1";
dm.datamodel = 13;
dm.tracking_weeks = 1;
(Иногда переменная «filterstr» содержит больше значений, например)
NB|JA|WS|AM
Я попробовал приведенный ниже код... но он не дал точного результата.
for (int i = 0; i < ListDoorData.Count(); i++)
{
if (!FilterStr.Contains(ListDoorData[i].GetType().GetProperty(FilterOrder)?.GetValue(ListDoorData[i])?.ToString()))
{
ListDoorData.Remove(ListDoorData[i]);
}
}
где «FilterOrder» может быть свойством класса «DoorDetails», например «brand», «buying_group» или «setting_name» и т. д.
Пожалуйста, помогите мне получить список<> элементов, которых нет в строковом значении ??? Спасибо.
Сначала вам нужно разделить элементы фильтра, затем вы можете использовать Linq Содержит
string[] filterItems = filterstr.Split('|');
var filteredData = ListDoorData
.Where(d => !filterItems.Contains(d.brand));
Если вы хотите отфильтровать исходный список, вы можете создать новый:
ListDoorData = filteredData.ToList();
или используйте List.RemoveAll, что я бы предпочел в данном случае:
ListDoorData.RemoveAll(d => filterItems.Contains(d.brand));
@KitKat, и если вам это нужно для большего количества свойств строкового типа, вы можете создать метод расширения, который использует Func<DoorDetails, string>
для выбора свойства для фильтрации.
Привет @Tim Schmelter Спасибо за ответ. Есть ли какой-либо общий способ использования, например ListDoorData.RemoveAll(d => filterItems.Contains(FilterOrder)); Потому что один и тот же метод фильтрации может использоваться для разных свойств, таких как «buying_group», «setting_name» или «datamodel» и т. д. Переменная FilterOrder может быть любым из этих свойств. Есть ли способ???
Да. Создайте FilterOrder
a Func<DoorDetails, string>
и вызовите ListDoorData.RemoveAll(d => filterItems.Contains(FilterOrder(d)));
, это означает, что вам просто нужен делегат, который принимает DoorDetail и возвращает соответствующую строку.
@Fildor Привет, если вы не возражаете, не могли бы вы уточнить свой ответ в колонке ответов ??? Я этого не понял.
@KitKat: я этого не понимаю. Вам нужно где-то знать, что вы хотите фильтровать по определенному свойству, там вы можете его использовать, например: ListDoorData.RemoveAll(d => filterItems.Contains(d.buying_group));
@Fildor: я бы переименовал расширение в RemoveBy
, иначе кто-то мог бы подумать, что выполняется поиск по элементам фильтра.
@TimSchmelter Вы правы ... с другой стороны, это была просто каракуля, демонстрирующая, на что способен ОП. И поскольку это всего лишь «вишенка на торте», может быть, лучше добавить ее к этому прекрасному ответу?
Улучшенный пример: dotnetfiddle.net/h933h6
Почему именно вы используете отражение? Это кажется ненужным.