Home > Software engineering >  How to filter the list by using LINQ
How to filter the list by using LINQ

Time:01-10

I have a list mentioned below.

var fakedata = new Dictionary<Gateway, List<FeMeasurementValues>>()
{
    {
        new Gateway { SiteId = 1, FirmwareVersion = "1.1.1", ConnectivityStatus = GatewayConnectivityStatus.ReadyToConnect },
                    new List<FeMeasurementValues>() { new FeMeasurementValues { MeasurementName = "MsgLRRID", Values = new List<FeValue> { new FeValue { Value = "FFFF123", Horodate = DateTime.Now } } } }
    },
    {
        new Gateway { SiteId = 2, FirmwareVersion = "1.1.2", ConnectivityStatus = GatewayConnectivityStatus.Connected },
                    new List<FeMeasurementValues>() { new FeMeasurementValues { MeasurementName = "MsgLRRID", Values = new List<FeValue> { new FeValue { Value = "GH67123", Horodate = DateTime.Now } } } }
    },
    {
        new Gateway { SiteId = 3, FirmwareVersion = "1.1.3", ConnectivityStatus = GatewayConnectivityStatus.Disconnected },
                    new List<FeMeasurementValues>() { new FeMeasurementValues { MeasurementName = "MsgLRRID", Values = new List<FeValue> { new FeValue { Value = " ", Horodate = DateTime.Now } } } }
    },
    {
        new Gateway { SiteId = 4, FirmwareVersion = "1.1.1", ConnectivityStatus = GatewayConnectivityStatus.Connected },
                    new List<FeMeasurementValues>() { new FeMeasurementValues { MeasurementName = "MsgLRRID", Values = new List<FeValue> { new FeValue { Value = "SA67123", Horodate = DateTime.Now } } } }
    }
};

I have two methods

  1. "GetPublicNetworkUsedCount()" which needs to return the count of Value which starts with "FFFF" So, In this case output should be 1.
  2. "GetPrivateNetworkUsedCount()" which needs to return the count of Value which does not starts with "FFFF" and which includes empty values. So, In this case output should be 3.

Below is what i have tried:

private static string GetPublicNetworkUsedCount(List<FeValue> values)
{
    var countofPublicNetwork = values.Where(x => x.Value.Any(f => x.Value.StartsWith("FFFF")));
    return countofPublicNetwork.Count().ToString();
}

private static string GetPrivateNetworkUsedCount(List<FeValue> values)
{
    var countofPrivateNetwork = values.Where(x => x.Value.Any(f => !x.Value.StartsWith("FFFF")));
    return countofPrivateNetwork.Count().ToString();
}

I'm getting the wrong output as 0 for GetPublicNetworkUsedCount and 1 for GetPrivateNetworkUsedCount.

Please help me.

CodePudding user response:

x.Value.Any() will return true as soon as the condintion inside is true. which leads to return 1 convertet to a number.

to get alll entries starting with FFFF remove the Any part like:

var countofPublicNetwork = values.Where(x =>x.Value.StartsWith("FFFF"));

you can get the count directly if you substitute .Where() with .Count() like Mark mentioned in his comment.

var countofPublicNetwork = values.Count(x =>x.Value.StartsWith("FFFF"));

CodePudding user response:

You have a List<FeValue>, where each object has a string Value. You are treating the string as a collection and going one step to deep, the .Any( is not needed.

So the check should just be

values.Where(x => x.Value.StartsWith("FFFF")).Count();

Or just

values.Count(x => x.Value.StartsWith("FFFF"));

CodePudding user response:

See comments:

//             vv I'd recommend to return int
private static string GetPublicNetworkUsedCount(List<FeValue> values)
{                                                       // vv Any doesn't make sense here: this is a string
    var countofPublicNetwork = values.Where(x => x.Value.Any(f => x.Value.StartsWith("FFFF")));
    return countofPublicNetwork.Count().ToString();
}

private static string GetPrivateNetworkUsedCount(List<FeValue> values)
{
    var countofPrivateNetwork = values.Where(x => x.Value.Any(f => !x.Value.StartsWith("FFFF")));
    return countofPrivateNetwork.Count().ToString();
}

So, I'd do something like this:

private static int GetPublicNetworkUsedCount(List<FeValue> values) 
    => values.Count(x => x.Value.StartsWith("FFFF"));


private static int GetPrivateNetworkUsedCount(List<FeValue> values)
    => values.Count(x => !x.Value.StartsWith("FFFF"));

The returned int can then be stringyfied if need be.


Maybe I'd even do

public static class FeValueListExtensions
{
    public static int GetPublicNetworkUsedCount(this List<FeValue> values) 
    => values.Count(x => x.Value.StartsWith("FFFF"));


    public static int GetPrivateNetworkUsedCount(this List<FeValue> values)
    => values.Count(x => !x.Value.StartsWith("FFFF"));
}

which can then be used as

// Assume we have a List<FeValue> defined as
List<FeValue> feValues = ...
var publicCount = feValues.GetPublicNetworkUsedCount();
  • Related