Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select the same list but with an additional variable set?

Tags:

c#

linq

I have a List<MyObject>

MyObject is as follows.

public class MyObject
{
   public bool available;
   public bool online;
}

Now when I retrieve this List<MyObject> from another function, only the available field is set. Now I want to set the online field of each MyObject.

What I currently do is

List<MyObject> objectList = getMyObjectList();
objectList.ForEach(x => x.online = IsOnline(x));

Now that the online property is set, I want to filter again using Where to select MyObject that is both available and online.

objectList.Where(x => x.available && x.online);

While I understand that the code above is working and readable, I am curious to know whether there is a LINQ way of selecting the same object but with a variable initialized so I can combine all the three lines to one line. Unfortunately ForEach does not return the list back.

Something like

getMyObjectList().BetterForEach(x => x.online = IsOnline(x)).Where(x => x.available && x.online);

BetterForEach will return x with the previous values set and with the online field set as well.

Is there any way function/way to achieve this using LINQ?

UPDATE
I've removed other fields of MyObject. MyObject does not only contain these fields but many more. I'd rather not create new instances of MyObject.

like image 637
Ranhiru Jude Cooray Avatar asked Nov 24 '25 01:11

Ranhiru Jude Cooray


2 Answers

The simplest solution is probably to make an extension method that is like ForEach but returns the list for chaining:

public static List<T> ForEachThen<T>(this List<T> source, Action<T> action)
{
    source.ForEach(action);
    return source;
}
like image 56
Rawling Avatar answered Nov 26 '25 17:11

Rawling


Linq is for querying data, not for updating it. So any option you have will not be too pretty, but there are still some options.

You could do this:

var result = 
    objectList.Select(x => 
    {
        x.online = IsOnline(x);
        return x;
    });

However, that is pretty bad practice. This would be better:

var result = 
    objectList.Select(x => new MyObject
    {
        available = x.available,
        online = IsOnline(x)
    });

But this creates a collection of new objects, not related to your original set.


This kind of code generally indicates there might be something wrong with your basic design. Personally, I'd go with something like this (if you can set up a static method to do the work of IsOnline):

public class MyObject
{
   public bool Available;
   public bool Online { get { return MyObjectHelper.IsOnline(this); } }
}

...
var result = objectList.Where(x => x.Available && x.Online);

Or if you can't set up a static method, maybe this field doesn't need to be in MyObject class at all?

public class MyObject
{
   public bool Available;
}
...
var result = objectList.Where(x => x.Available && IsOnline(x));
like image 39
p.s.w.g Avatar answered Nov 26 '25 16:11

p.s.w.g



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!