从列表中合并数据集层次结构

Merging Data Set hierarchies From a List

我试图尽可能地完成。

我有一个 class 有一个 属性 实际上可以自己拿着。让我们调用class 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
              ....
         }
     }
}

我想找到一种方法来诅咒这个列表并组合这些项目,以便将它们组织在一个适当的层次结构中,这样德克萨斯州的所有县都属于一个德克萨斯州集。同县城同理。

期望的结果类似于:

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;
        }

正如我之前在评论中提到的,我确实会使用 ISet 数据结构,例如 HashSet(我将在下面的代码片段中使用)。我建议使用两个 classes,因为 Item 不应该知道其他项目。你应该有一个 class 来封装一个 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);
         }

   }