我试图尽可能地通过。
我有一个类,它有一个实际上可以保持自己的属性。我们打电话给班级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;
}
答案 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);
}
}