How to filter a list using linq depends on counting a property in the same list and getting a random group of at least minimum sum

Here is my problem, I tried this query (apart from numOfIps, which I want to be a static number)

    ips.Where(ip =>!ips.Any(
                            tempIp => tempIp.VLanID != null 
                                && tempIp.VLanID == ip.VLanID 
                                && (tempIp.PackageId > 0 || tempIp.IsReserved !=0))
                        && ip.PackageId == 0
                        && ip.IsReserved == 0
                        ).ToList();

      

RESULTS FROM QUESTION OF QUALIFIED SHEETS (NOT EXPECTED)

IP 100.100.101 WITH VLANID 100 isReserved = 0  PackageId = 0    
IP 100.100.102 WITH VLANID 100 isReserved = 0 PackageId = 0    
IP 400.400.401 WITH VLANID 400 isReserved = 0  PackageId = 0    
IP 400.400.402 WITH VLANID 400 isReserved = 0 PackageId = 0

      

DANGEROUS LIST OF RESULTS

IP 100.100.101 WITH VLANID 100 isReserved = 0  PackageId = 0    
IP 100.100.102 WITH VLANID 100 isReserved = 0 PackageId = 0

      

DETAILS

TEST LIST

IP 100.100.101 WITH VLANID 100 isReserved = 0  PackageId = 0
IP 100.100.102 WITH VLANID 100 isReserved = 0 PackageId = 0

      

(no other ip with VLANID == 100 in the ips list)

IP 200.200.201 WITH VLANID 200 isReserved = 0 PackageId = 0 
IP 200.200.202 WITH VLANID 200 isReserved = 0 PackageId = 1

      

(no other IP with VLANID == 200 in the ips list)

IP 300.300.301 WITH VLANID NULL isReserved = 0 PackageId = 0 
IP 300.300.302 WITH VLANID NULL isReserved = 0 PackageId = 0
IP 400.400.401 WITH VLANID 400 isReserved = 0  PackageId = 0
IP 400.400.402 WITH VLANID 400 isReserved = 0 PackageId = 0

      

I want to take an arbitrary ips group (belonging to the same vlanId) from the ips list, that:

  • no ip with the same vlanid which has PackageId> 0 || IsReserved! = 0

  • this group has at least numOfIps

  • I want to take the first group that meets these rules, not all groups with different vlanids (somehow different or firstordefault ... I don't know)

I want to help me fix this query or create a new one using linq.

+3


source to share


2 answers


Not sure how you wanted to handle null vlanids ... have you ever wanted to return them? If so, just add a.Where (v => v.vlandid! = Null) at the end of the other Where clauses. The provided code can be dumped into LinqPad (using operators). Feel free to play with it as needed.

var ips= new[]{
  new {ip="100.100.101",VLanID=(int?)100,isReserved=0,PackageId=0},
  new {ip="100.100.102",VLanID=(int?)100,isReserved=0,PackageId=0},
  new {ip="200.200.201",VLanID=(int?)200,isReserved=0,PackageId=0},
  new {ip="200.200.202",VLanID=(int?)200,isReserved=0,PackageId=1},
  new {ip="300.300.301",VLanID=(int?)null,isReserved=0,PackageId=0},
  new {ip="300.300.302",VLanID=(int?)null,isReserved=0,PackageId=0},
  new {ip="400.400.401",VLanID=(int?)400,isReserved=0,PackageId=0},
  new {ip="400.400.402",VLanID=(int?)400,isReserved=0,PackageId=0}
};
var numOfIps=2;
var result=ips.GroupBy(k=>k.VLanID)
 .Where(v=>v.Count()>=numOfIps)
 .Where(v=>v.All(i=>i.isReserved==0))
 /*.Where(v=>v.Key!=null)  Remove null vlans */
 /*.OrderBy(x => Guid.NewGuid()) Pseudo Randomize */
 .First(v=>v.All(i=>i.PackageId==0))
 .Select(v=>v);

result.Dump();

      



Result

+4


source


You can group the results with VLanID

and return the first one:

ips.Where(ip => !ips.Any(
        tempIp => tempIp.VLanID != null
            && tempIp.VLanID == ip.VLanID
            && (tempIp.PackageId > 0 || tempIp.IsReserved != 0))
    && ip.PackageId == 0
    && ip.IsReserved == 0
    ).GroupBy(i => i.VLanID).First().ToList();

      



If the result may be empty, you should use FirstOrDefault

and then eliminate unnecessary cases. I also do not know how you use the result as IGrouping

a IEnumerable

conversion .ToList()

may not be necessary.

+2


source







All Articles