LINQ - предложение Where с логическим методом - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть следующие классы.Моя цель - отфильтровать Компоненты на основе productTypeField и downloadSpeedField.У меня есть список lstFilteredComps, в который я хочу добавить компонент INTERNET productType, имеющий значение downloadSpeed ​​меньше или равно только 5, если существует число компонентов больше 5.Если все компоненты меньше или равны downloadSpeed ​​5, он должен добавить компонент INTERNET с downloadSpeed ​​меньше, чем 5.

Классы :

 public ct_Component[] Components {
 get {
     return this.componentsField;
 }
 set {
    this.componentsField = value;
 }
    }

public partial class ct_Component
{
    private string descriptionField;
    private string downloadSpeedField;
    private string productTypeField;
}

Я пыталсяследующий код, но он удаляет компоненты с downloadSpeed ​​5 во всех случаях, как я помещу условие, чтобы проверить, существует ли downlaodSpeed ​​больше 5 или нет.То есть мой код должен удалять компоненты, только если доступно более высокое значение, или, другими словами, FilterInternetComponentLessThan5MB следует вызывать только при наличии более 5 МБ компонентов downloadSpeed.

ct_Component[] Components = response;
foreach (ct_Component comp in Components.Where(c => FilterInternetComponentLessThan5MB(c)))
{
    list<ct_Component> lstFilteredComps= //add filtered components;
}

Метод FilterComponentLessThan5MB

private bool FilterComponentLessThan5MB(ct_Component component)
{
    if (component.productType != "INTERNET" || (component.productType == "INTERNET"
        && int.Parse(Regex.Replace(component.downloadSpeed, @"[^\d]", "")) > 5))
    {
        return true;
    }
    else
        return false;
}

Мне нужна проверка, например:

foreach (ct_Component comp in Components.Where(Components.any(x=>x.productType == "INTERNET" && int.Parse(Regex.Replace(x.downloadSpeed, @"[^\d]", "")) > 5) ? true :  FilterInternetComponentLessThan5MB(c)))

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Имеется пара предикатных функций:

bool FilterNotInternetComponentOrOver5Mb(ct_Component component) =>
    (component.productTypeField != "INTERNET") ||
    (int.Parse(Regex.Replace(component.downloadSpeedField, @"[^\d]", "")) > 5);

bool FilterInternetComponentOver5Mb(ct_Component component) =>
    component.productTypeField == "INTERNET" &&
        int.Parse(Regex.Replace(component.downloadSpeedField, @"[^\d]", "")) > 5;

. Вы можете фильтровать по любому из более чем 5, используя:

var hasOver5 = Components.Any(c => FilterInternetComponentOver5Mb(c));
var lstFilteredComps = Components.Where(c => !hasOver5 || FilterNotInternetComponentOrOver5Mb(c)).ToList();
0 голосов
/ 01 февраля 2019

Возможно, вы ищете метод Any, который получает закрытый параметр, аналогичный Where, но возвращает логическое значение, как если бы один из элементов в коллекции оценивал значение true для вашего предиката.

В итоге вы получите что-то вроде этого:

ct_Component[] components = response;
if (components.Any(c => c.DownloadSpeedNumber > 5))
{
    var newList = new List<ct_Component>();
    foreach (ct_Component comp in components.Where(FilterInternetComponentLessThan5MB))
    {
        //add filtered components to newList.
    }

Где DownloadSpeedNumber может быть методом получения или расширения, который безопасно анализирует существующее поле downloadSpeed.

KeepИмейте в виду, что вы будете перебирать массив в методе Any, поэтому, если у вас действительно большой массив, вы можете пересмотреть использование Linq и просто использовать регулярное выражение для и повторять его только один раз.

...