从列表

时间:2018-03-21 18:32:38

标签: c# list tree hierarchy

我试图尽可能地通过。

我有一个类,它有一个实际上可以保持自己的属性。我们打电话给班级ItemSet。项集有一个名为 Add 的方法,允许将一个集添加到正在调用Add()的集合中。

套装

    public class ItemSet
    {
        public string Name{get; set;}
        public List<ItemSet> ItemSets {get; set;}

        public void Add(ItemSet) 
        {
                ItemSets.Add(ItemSet); //Not exactly how is but this example should work.
        }
   }

所以......让我说我有这些套装的清单。 List<ItemSet> setList; 此列表表示可用的每个可能的层次结构组合。

对于谈话,我们说这些代表州,县,城市和层次结构。我正在使用JSON,如下面的符号来说明我正在使用的内容。

setList[0] = 
{
     Name:Texas,
     ItemSet : 
     {
         Name: Tarrant,
         ItemSet : 
         { 
              Name: Fort Worth
              ....
         }
     }
}
setList[1] = 
{
     Name:Texas,
     ItemSet : 
     {
         Name: Tarrant,
         ItemSet : 
         { 
              Name: Arlington
              ....
         }
     }
}
setList[2] = 
{
     Name:Texas,
     ItemSet : 
     {
         Name: Dallas,
         ItemSet : 
         { 
              Name: Dallas
              ....
         }
     }
}
setList[3] = 
{
     Name:Texas,
     ItemSet : 
     {
         Name: Dallas,
         ItemSet : 
         { 
              Name: Plano
              ....
         }
     }
}
setList[4] = 
{
     Name:Washington,
     ItemSet : 
     {
         Name: King,
         ItemSet : 
         { 
              Name: Seatle
              ....
         }
     }
}

我想找到一种方法来诅咒这个列表,并将这些项目组合在一起,以便将它们组织在一个专业的hiereachy中,这样德克萨斯州的所有县都属于德克萨斯州的一套。同样适用于同一个县的城市。

期望的结果类似于:

newList[0]
{
    Name: Texas
    ItemSet  :
    {
        Name:Tarrant
        ItemSet:
        { 
            Name:Fort Worth
        }
        ItemSet:
        {
            Name: Arlington
        }

    }
    ItemSet  :
    {
        Name:Dallas
        ItemSet:
        { 
            Name:Dallas
        }
        ItemSet:
        {
            Name: Plano
        }

    }
}
newList[1] = 
{
    Name:Washington
    ItemSet:
    {
        Name:King
        ItemSet:
        {
             Name: Seatle
        }
    }
}

换句话说,我想创建一个只包含两个ItemSet的新列表(每个州一个)。使用适当的ItemSet.Add();

将填充相应的县和城市级别

请注意,此层次结构中可能存在无限量的级别。这里不仅仅是3。

到目前为止,这里有我所拥有的,但我觉得我正朝着错误的方向前进:

我将列表中的每个ItemSet称为一个块。

public static List<ItemSet> CombineChunks(List<ItemSet> chunks)
{
     List<ItemSet> combinedChunks = new List<ItemSet>();
     //do stuff with chunks

     foreach (var chunk in chunks)
     {
         bool add = true;
         if (combinedChunks.Count == 0)
             combinedChunks.Add(chunk);
         else
         {
            foreach (var c in combinedChunks)
            {
               if (c.Name == chunk.Name)
               {
                  add = false;
                  //move on to child
               }

               if (add == true)
               {
                 combinedChunks.Add(chunk);
               }
            }
            return combinedChunks;
        }

1 个答案:

答案 0 :(得分:1)

正如我之前在评论中提到的,我确实使用了一个ISet数据结构,例如HashSet(我将在下面的代码片段中使用)。我建议使用两个类,因为Item不应该知道其他项目。你应该有一个类来封装一个Item和一个ItemMerger的数据,它可以把你所有的项都放在一个结构中。

    public class Location
    {
        public string State { get; set;}
        public string Country { get; set;}
        public string City {get; set;}
   }

   public class LocationComparer : IEqualityComparer<Location>
   {
        public bool Equals(Location x, Location y)
        {
             if(x == null || y == null) 
                 return false; 

             return x.State.Equals(y.State) &&
                    x.Country.Equals(y.Country) && 
                    x.City.Equals(y.City);
        }

        public int GetHashCode(Location loc) 
        {
             if(loc == null) 
                 return 0; 

             var value = 0; 
             if(!string.IsNullOrEmpty(loc.Country))
                value += loc.Country.Length; 

             if(!string.IsNullOrEmpty(loc.State))
                value += loc.State.Length; 

             if(!string.IsNullOrEmpty(loc.City))
                 value += loc.City.Length;

             return length * 89;
        }
   } 

   public class LocationMerger 
   {
         private readonly LocationComparer _comparer = new LocationComparer();

         public Dictionary<string, HashSet<Location>> Locations { get; set;} 

         public LocationMerger()
         {
              Locations = new Dictionary<string, HashSet<Location>>() // will use your custom comparer to check for unique Location instances 
         }

         public void AddChunks(string locationIdentifier,  IEnumerable<Location> locs)
         {
               var hashSet = new HashSet<Location>(_comparer);
               foreach(var l in locs)
                   hashSet.Add(l); 

               Locations.Add(locationIdentifier, hashSet);
         }

   }