-1

I have a SourceList of objects representing machines on a network and each machine itself has a SourceList of devices connected to that machine.

I would like to flatten the list of devices across all machines into another SourceList, so that any changes to either the Machines SourceList or the Devices SourceList get reflected in the new list.

canice
  • 343
  • 4
  • 14
  • Try [LINQ](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.selectmany?view=netcore-3.1) `SelectMany()`. Need more details for better answers. – Jacob Huckins Jun 24 '20 at 20:26
  • Please [edit] your question to include the source code you have and the source code you have tried to solve the problem. Provide a [mcve] if possible. – Progman Jun 24 '20 at 20:54

1 Answers1

0

You can use TransformMany() which will flatten your inner lists into one list. See the following example:

public class Device {
    public string Name {get; set;}
}

public class Machine {
    public ISourceList<Device> Devices {get;} = new SourceList<Device>();

    public string Host {get; set;}
}

public class Program
{
    public static void Main()
    {
        ReadOnlyObservableCollection<Device> list;

        ISourceList<Machine> machines = new SourceList<Machine>();
        machines
            .Connect()
            .TransformMany(it => it.Devices)
            .Bind(out list)
            .OnItemAdded(it => {
                Console.WriteLine("### Device added: "+it.Name+" ###");
            })
            .OnItemRemoved(it => {
                Console.WriteLine("### Device removed: "+it.Name+" ###");
            })
            .Subscribe();

        Machine m1 = new Machine {
            Host = "local"
        };
        machines.Add(m1);
        Device d1 = new Device {
            Name = "keyboard"
        };
        Console.WriteLine("Add d1 to m1");
        m1.Devices.Add(d1);

        Machine m2 = new Machine {
            Host = "remote"
        };
        Device d2 = new Device {
            Name = "mouse"
        };
        m2.Devices.Add(d2);
        Console.WriteLine("Add m2, which has a d2");
        machines.Add(m2);

        Device d3 = new Device {
            Name = "webcam"
        };
        Console.WriteLine("Add d3 to m1");
        m1.Devices.Add(d3);

        Console.WriteLine("Remove m1");
        machines.Remove(m1);

        Console.WriteLine("Remove m2");
        machines.Remove(m2);
    }
}

This will generate the following output:

### Device added: keyboard ###
Add m2, which has a d2
### Device added: mouse ###
Add d3 to m1
### Device added: webcam ###
Remove m1
### Device removed: keyboard ###
### Device removed: webcam ###
Remove m2
### Device removed: mouse ###

As you see, when you add a machine or add a device, the list gets updated. Also, when a machine is remove the device entries are "cleaned up" from the list as well.

Progman
  • 13,123
  • 4
  • 28
  • 43