从列表中合并数据集层次结构
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);
}
}
我试图尽可能地完成。
我有一个 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);
}
}