简体   繁体   中英

How to filter the list by using LINQ

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.

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"));

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"));

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM