如何使用C#在自定义词典中添加元素?

时间:2016-03-29 08:38:21

标签: c# list dictionary nested add

我在C#中名为Cluster的类中有一个用于聚类目的的字典:

Dictionary<int, List<ClusterMember>>

int代表群集ID List<ClusterMember>>代表群集ID 和{{中的成员 1}}是另一个类。我在这里展示了整个代码结构:

ClusterMember

虽然我在这个方法中使用了这些类:

public class ClusterMember
{
    public string _name { get; set; }
}

public class Cluster
{
    public Dictionary<int, List<ClusterMember>> _dic { get; set; }  

    public Cluster(int _id, List<ClusterMember> _clusMem)
    {
       _dic.Add(_id, _clusMem);
    }
}  

现在如何在public static List<Cluster> DP_Cluster(List<string> _customer, double _alpha) { var _currentClusters = 0; // current number of clusters i.e. "k" var _memberNumber = 0; // running member number i.e. "n" //var _dic = new Dictionary<int, List<string>>(); var _probOld = 0.0; var _probNew = 0.0; List<Cluster> _myClusters = new List<Cluster>(); //Cluster _cluster = new Cluster(?); // How to Add cluster using above classes // How to Add cluster Member using above classes _myClusters.Add(_cluster); //_dic.Add(_currentClusters, _customer.ElementAt(_memberNumber)); _currentClusters += 1; for(int _i = 1; _i < _customer.Count - 1; _i++) { if( _i <= _currentClusters) { _probOld = myClusters[_i].Members.Count / ((_i+1) - 1 + _alpha); } else { _probNew = _alpha / ((_i+1) - 1 + _alpha); } if(_probNew > _probOld) { // Add _customer.ElementAt(_memberNumber+=1) to New Cluster Cluster cluster = new Cluster( _currentClusters += 1 ); myClusters.Add(cluster); } else { // Add _customer.ElementAt(_memberNumber+=1) to Old Cluster } } return myClusters; } 中添加_dic Dictionary对象?此外,我可能不得不多次向同一for loop添加多个集群成员

  • 我可以在迭代中将集群成员添加到_id
  • 然后必须将集群成员添加到另一个成员中的_id = 1 迭代中,
  • 然后它可能会将另一个集群成员添加到同一个ID,即_id = 2,反之亦然。

此外,如果可以使用_id = 1(默认情况下不是1 0启动群集ID ,对我来说会更有意义} index )。

4 个答案:

答案 0 :(得分:0)

  

此外,我可能需要将多个集群成员添加到同一个ID   不止一次

您可以检查每个循环迭代的关键字:

public void AddInCluster(int id, List<ClusterMember> _clusMem)
{
    if (_dic.ContainsKey(id))
    {
        foreach (var clusterMember in _clusMem)
        {
            _dic[id].Add(clusterMember);                    
        }
    }
    else
    {
        _dic.Add(id, _clusMem);
    }
}

或者您可以使用词典中的TryGetValue:

public void AddInCluster(int id, List<ClusterMember> _clusMem)
{
    List<ClusterMember> members;
    if (_dic.TryGetValue(id, out members))
    {
        foreach (var clusterMember in _clusMem)
        {
            members.Add(clusterMember);
        }
    }
    else
    {
        _dic.Add(id, _clusMem);
    }       
}
  

此外,如果有可能开始,对我来说会更有意义   群集ID为1

int包装到ClusterId类中,如果id为0,可能会引发异常怎么样? 此外,您的Cluster类可以覆盖字典上的访问器运算符[],以在您的上下文中提供有意义的抽象(例如,从1开始而不是0)

您还可以像Get一样添加Add,以检查此ID是否存在:

public List<ClusterMember> GetFromCluster(ClusterId id)
{
    if (_dic.ContainsKey(id))
    {
        return _dic[id];
    }

    throw new ClusterDoesNotContainsThisId(id);
}

答案 1 :(得分:0)

如何使用Dictionaries Add方法?像:

if(needToAddNewCluster){
    _dic.Add(index, new List<ClusterMember>());
}
if(needToExtendCluster){
    _dic[index].Add(clusMem);
}

在此我假设needToAddNewCluster检查_dic.ContainsKey(index)

答案 2 :(得分:0)

您可以将方法添加到Cluster类

public void AddToCluster(int id, ClusterMember member)
{
    // checks if cluster with specific id is already in Dictionary
    if(!_dic.ContainsKey(id))
       _dic.Add(id,new List<ClusterMember>());

     _dic[id].Add(member);
}

你可以像这样在迭代中使用它

int id = 1; // cluster id
foreach(var m in members)
{
   // adding members to cluster with id = 1
   cluster.AddToCluster(id,m);
}

更新

我们也可以获得每个群集ID的列表计数,即每个群集ID的群集成员数量?

您可以添加这两种方法

// get members count for specific cluster id
public int GetCount(int id)
{
     return _dict[id].Count;
}

// get members count for all clusters
public Dictionary<int,int> GetCounts()
{
    return _dict.ToDictionary(k=>k.Key,v=>v.Value.Count);
}

您可以像这样访问

var counts = cluster.GetCounts();
var c1Cnt=counts[1]; // 1 is cluster id

答案 3 :(得分:0)

我将稍微更改Culster类的实现。 _dic应该是带有初始化程序的仅getter属性。根据通常的.NET C#命名约定,属性应位于PascalCase中,因此我将其重命名为Dic。 (更好的名称是MemberDictionaryMembers)。带下划线的_camelCase标识符通常用于字段。方法参数和局部变量具有camelCase。

然后添加用于添加一个或几个成员的新方法。两种方法都首先检查列表是否已经存在。如果有,则将新成员添加到列表中,否则将使用新成员初始化一个新列表,然后将其添加到字典中。

public class Cluster
{
    public Dictionary<int, List<ClusterMember>> Dic { get; }
        = new Dictionary<int, List<ClusterMember>>();

    // Initialize empty cluster.
    public Cluster()
    {
    }

    // Initialize cluster with one initial member.
    public Cluster(int key, ClusterMember member)
    {
        Add(key, member);
    }

    // Initialize cluster with many members.
    public Cluster(int key, IEnumerable<ClusterMember> members)
    {
        Add(key, members);
    }

    // Allows you to a one new member.
    public void Add(int key, ClusterMember member)
    {
        if (Dic.TryGetValue(key, out var memberList)) {
            memberList.Add(member);
        } else {
            memberList = new List<ClusterMember> { member };
            Dic.Add(key, memberList);
        }
    }

    // Allows you to add many members.
    public void Add(int key, IEnumerable<ClusterMember> members)
    {
        if (Dic.TryGetValue(key, out var memberList)) {
            memberList.AddRange(members);
        } else {
            memberList = new List<ClusterMember>(members);
            Dic.Add(key, memberList);
        }
    }
}

此实现委派字典和列表的创建以及将成员添加到Cluster类的详细信息。

顺便说一句:词典使用键而不是索引。


我不知道您从哪里获得会员编号,也不了解您的聚类算法;但是,我认为经过DP_Cluster的这些更改可能看起来像这样:

public static List<Cluster> DP_Cluster(List<string> customers, double alpha)
{
    double probOld = 0.0;
    double probNew = 0.0;

    var clusters = new List<Cluster>();
    Cluster currentCluster = null;

    for (int i = 0; i < customers.Count; i++) {
        if (i <= clusters.Count) {
            probOld = clusters[i].Dic.Count / (i + alpha);
        } else {
            probNew = alpha / (i + alpha);
        }

        if (probNew > probOld || currentCluster == null) {
            currentCluster = new Cluster();
            clusters.Add(currentCluster);
        }
        currentCluster.Add(_memberNumber, new ClusterMember { Name = customers[i] });
    }

    return clusters;
}

Cluster中的某些构造函数和方法最终可能被证明是多余的,因为我们总是每次一次添加一个客户。