简体   繁体   English

将对象属性值转换为字典

[英]Converting object property values to dictionary

Lets say, I have a list of objects like this 可以说,我有一个像这样的对象列表

public class Room{
    public string Name {get; set;}
    public int[] UserId {get; set;}
}

What could be an efficient way of converting this list to dictionary like the following 什么是将此列表转换为字典的有效方式,如下所示

Dictionary<int, List<string>> 

where the key is the UserId and String is the name of the room. 其中键是UserId,String是房间的名称。 Thanks in Advance. 提前致谢。

I would use Linq's Aggregate method as shown below. 我会使用Linq的Aggregate方法,如下所示。 ( Note I took liberties with the original object to be a List vs an array for the demo, but you can change that ). 注意我将原始对象的自由作为一个List vs一个数组用于演示,但你可以改变它 )。

var names = new List<Room>()
{
    new Room() { Name = "Alpha", UserId = new List<int> { 10, 40 }},
    new Room() { Name = "Omega", UserId = new List<int> { 10, 20, 30 }},
};

// Aggregate needs an item to pass around, we will
// seed it with the dictionary which will be the ultimate returned
// value. The following lambda takes a dictionary object (`dict`)
// and the current room ('current') to add to the dictionary. 
names.Aggregate (new Dictionary<int, List<string>>(), (dict, current) =>
            {
               current.UserId.ForEach(id => {
                                               if (dict.ContainsKey(id) == false)
                                                  dict.Add(id, new List<string>());

                                               dict[id].Add(current.Name);
                                            });
                return dict;
            });

Result: 结果:

在此输入图像描述

Concept 概念

  • Iterate through the List of Rooms. 遍历房间列表。
  • If the dictionary contains the UserID add the name to the associated list. 如果字典包含UserID,则将名称添加到关联列表。
  • Otherwise make a new dictionary item. 否则制作一个新的字典项目。

Implementation 履行

foreach (Room r in RoomsList) {
    foreach (int id in r.UserID) {
        if (RoomDictionary.Contains(id))
            RoomDictionary[id].Add(r.Name);
        else
            RoomDicationary.Add(id, new List<string>() { r.Name });
    }
}

Or something like that I just typed that into the web browser so it may need some adjusting but something like that. 或者类似的东西,我只是在网络浏览器中键入它,所以它可能需要一些调整,但类似的东西。

Just some clarification, since UserId is declared as an array from your class Room. 只是一些澄清,因为UserId被声明为类Room中的数组。 Assuming it is not an array, and 1 id corresponds to 1 room name. 假设它不是数组,1个id对应1个房间名称。 A RoomCollection implementing IDictionary would give you better control as shown below: 实现IDictionary的RoomCollection将为您提供更好的控制,如下所示:

 public class RoomCollection : IDictionary<int, string>
{
    private Dictionary<int, string> roomCollection = new Dictionary<int, string>();

    //Add modified version of Add()
    public void Add(Room room)
    {
        //Do something to efficiently check whether room already exists
        this.Add(room.UserId, room.Name);
    }

    public void Add(int key, string value)
    {
        //Checking can be done here
        if (this.roomCollection.ContainsKey(key))
        {
            this.roomCollection[key] = value; //Overwrite values
        }
        else
        {
            this.roomCollection.Add(key, value); //Create new item
        }
    }

    //Modify other functionalities to your own liking
    public bool ContainsKey(int key)
    {
        return this.roomCollection.ContainsKey(key);
    }

    public ICollection<int> Keys
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(int key)
    {
        throw new NotImplementedException();
    }

    public bool TryGetValue(int key, out string value)
    {
        throw new NotImplementedException();
    }

    public ICollection<string> Values
    {
        get { throw new NotImplementedException(); }
    }

    public string this[int key]
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public void Add(KeyValuePair<int, string> item)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        throw new NotImplementedException();
    }

    public bool Contains(KeyValuePair<int, string> item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(KeyValuePair<int, string>[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    public int Count
    {
        get { throw new NotImplementedException(); }
    }

    public bool IsReadOnly
    {
        get { throw new NotImplementedException(); }
    }

    public bool Remove(KeyValuePair<int, string> item)
    {
        throw new NotImplementedException();
    }

    public IEnumerator<KeyValuePair<int, string>> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

public class Room
{
    public string Name { get; set; }
    public int UserId { get; set; }
}

public class TestCollection
{
    public void Test()
    {
        Room r1 = new Room();
        r1.UserId = 1;
        r1.Name = "Room One";

        Room r2 = new Room();
        r2.UserId = 2;
        r2.Name = "Room Two";

        RoomCollection roomCollection = new RoomCollection();
        roomCollection.Add(r1);
        roomCollection.Add(r2);

        foreach (int roomId in roomCollection.Keys)
        {
            Console.WriteLine("Room number: {0} - Room name: {1}", roomId, roomCollection[roomId]);
        }
    }
}

This seems quite straight forward: 这似乎很直接:

var rooms = new List<Room>()
{
    new Room() { Name = "Alpha", UserId = new List<int>() { 10, 40 }.ToArray() },
    new Room() { Name = "Omega", UserId = new List<int>() { 10, 20, 30 }.ToArray() },
};

var query =
    from r in rooms
    from u in r.UserId 
    group r.Name by u;

var result = query.ToDictionary(x => x.Key, x => x.ToList());

The result I get is: 我得到的结果是:

结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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