C# 阿扁词典<;字符串,HashSet<;字符串>&燃气轮机;
这件事我已经搞了好几天了,我都想不起来了: 我的结构如下:C# 阿扁词典<;字符串,HashSet<;字符串>&燃气轮机;,c#,dictionary,hashset,C#,Dictionary,Hashset,这件事我已经搞了好几天了,我都想不起来了: 我的结构如下: Dictionary<string, HashSet<string>> 其中,p前缀值是字典键,S前缀值是哈希集值 我需要的是以下输出列表 P1, P2, S1, S2 在这种情况下,我将具有以下起始值: P1 S1, S2 P2 S1 输出列表应为: P1, P2, S1, P1, S2 如果在几个字典项的哈希集中有相似的值,它应该将它们组合在一起,这就是为什么P1,P2有S1,P1只有
Dictionary<string, HashSet<string>>
其中,p前缀值是字典键,S前缀值是哈希集值
我需要的是以下输出列表
P1, P2, S1, S2
在这种情况下,我将具有以下起始值:
P1 S1, S2
P2 S1
输出列表应为:
P1, P2, S1, P1, S2
如果在几个字典项的哈希集中有相似的值,它应该将它们组合在一起,这就是为什么P1,P2有S1,P1只有S2
下面是一个小测试页,可以进一步说明:
static void Main(string[] args)
{
var start = new Dictionary<string, HashSet<string>>();
var output = new List<string>();
//example1
start.Add("P1", new HashSet<string> { "S1", "S2" });
start.Add("P2", new HashSet<string> { "S1", "S2" });
output = HocusPocus(start);
PrintResult(output); // should be P1, P2, S1, S2
//example 2
start.Clear();
start.Add("P1", new HashSet<string> { "S1", "S2" });
start.Add("P2", new HashSet<string> { "S1" });
output = HocusPocus(start);
PrintResult(output); // should be P1, P2, S1, P1, S2
//example 3
start.Clear();
start.Add("P1", new HashSet<string> { "S1", "S2", "S3" });
start.Add("P2", new HashSet<string> { "S1" });
start.Add("P3", new HashSet<string> { "S1", "S2" });
output = HocusPocus(start);
PrintResult(output); // should be P1, P2, P3, S1, P1, P3, S2, P1, S3
Console.ReadKey();
}
public static List<string> HocusPocus(Dictionary<string, HashSet<string>> data)
{
// magic happens here
}
public static void PrintResult(List<string> result)
{
result.ForEach(x => Console.Write($"{x},"));
Console.WriteLine();
}
static void Main(字符串[]args)
{
var start=newdictionary();
var输出=新列表();
//例1
添加(“P1”,新哈希集{“S1”,“S2”});
添加(“P2”,新哈希集{“S1”,“S2”});
输出=HocusPocus(启动);
PrintResult(输出);//应该是P1、P2、S1、S2
//例2
start.Clear();
添加(“P1”,新哈希集{“S1”,“S2”});
Add(“P2”,新哈希集{“S1”});
输出=HocusPocus(启动);
PrintResult(输出);//应该是P1、P2、S1、P1、S2
//例3
start.Clear();
添加(“P1”,新哈希集{“S1”、“S2”、“S3”});
Add(“P2”,新哈希集{“S1”});
Add(“P3”,新哈希集{“S1”,“S2”});
输出=HocusPocus(启动);
PrintResult(输出);//应该是P1、P2、P3、S1、P1、P3、S2、P1、S3
Console.ReadKey();
}
公共静态列表HocusPocus(字典数据)
{
//魔法在这里发生
}
公共静态无效打印结果(列表结果)
{
result.ForEach(x=>Console.Write($“{x},”);
Console.WriteLine();
}
对于每个S,您似乎都希望找到与该S关联的所有p,并且使用相同的p值集对S值进行分组。如果你的数据集不是很大,你可以很简单地做到这一点,如果不是以最有效的方式
您的数据:
var start = new Dictionary<string, HashSet<string>> {
{ "P1", new HashSet<string> { "S1", "S2", "S3" } },
{ "P2", new HashSet<string> { "S1" } },
{ "P3", new HashSet<string> { "S1", "S2" } }
};
要能够按p值序列分组,需要一个IEqualityComparer
:
class SequenceEqualityComparer : IEqualityComparer<IEnumerable<string>>
{
// Does not handle null values correctly.
public bool Equals(IEnumerable<string> x, IEnumerable<string> y) => x.SequenceEqual(y);
public int GetHashCode(IEnumerable<string> obj)
{
unchecked {
return obj.Aggregate(17, (hash, @string) => hash * 23*@string.GetHashCode());
}
}
}
您可以打印查找:
foreach (var items in lookup)
{
Console.Write(string.Join(" ", items.Key));
Console.Write(" ");
Console.WriteLine(string.Join(" ", items));
}
似乎每个S都希望找到与该S关联的所有p,并且使用相同的p值集将S值分组。如果你的数据集不是很大,你可以很简单地做到这一点,如果不是以最有效的方式 您的数据:
var start = new Dictionary<string, HashSet<string>> {
{ "P1", new HashSet<string> { "S1", "S2", "S3" } },
{ "P2", new HashSet<string> { "S1" } },
{ "P3", new HashSet<string> { "S1", "S2" } }
};
要能够按p值序列分组,需要一个IEqualityComparer
:
class SequenceEqualityComparer : IEqualityComparer<IEnumerable<string>>
{
// Does not handle null values correctly.
public bool Equals(IEnumerable<string> x, IEnumerable<string> y) => x.SequenceEqual(y);
public int GetHashCode(IEnumerable<string> obj)
{
unchecked {
return obj.Aggregate(17, (hash, @string) => hash * 23*@string.GetHashCode());
}
}
}
您可以打印查找:
foreach (var items in lookup)
{
Console.Write(string.Join(" ", items.Key));
Console.Write(" ");
Console.WriteLine(string.Join(" ", items));
}
下面是的一个版本,它遍历主字典一次以构建反向字典,并使用集合而不是序列(它也在原始方法签名中工作):
公共静态列表HocusPocus(字典数据)
{
var invert=新字典();
foreach(数据中的var kvp)
{
foreach(以kvp.值表示的var s)
{
如果(!invert.TryGetValue,out var pvalues))
{
pvalues=新的HashSet();
反转[s]=pvalues;
}
pvalues.Add(kvp.Key);
}
}
变量查找=反转
.ToLookup(=>0.Value,=>0.Key,new SetComparer());
var flat=新列表();
foreach(查找中的变量项)
{
flat.AddRange(项.键);
平面。添加范围(项目);
}
返回平面;
}
公共类集合比较程序:IEqualityComparer
{
公共布尔等于(ISet x,ISet y)
{
返回x.SetEquals(y);
}
公共int GetHashCode(ISet obj)
{
未经检查
{
int hash=19;
foreach(对象中的变量foo)
{
hash=hash*31+foo.GetHashCode();
}
返回散列;
}
}
}
以下是的一个版本,它遍历主字典一次以构建反向字典,并使用集合而不是序列(它也可以在原始方法签名中工作):
公共静态列表HocusPocus(字典数据)
{
var invert=新字典();
foreach(数据中的var kvp)
{
foreach(以kvp.值表示的var s)
{
如果(!invert.TryGetValue,out var pvalues))
{
pvalues=新的HashSet();
反转[s]=pvalues;
}
pvalues.Add(kvp.Key);
}
}
变量查找=反转
.ToLookup(=>0.Value,=>0.Key,new SetComparer());
var flat=新列表();
foreach(查找中的变量项)
{
flat.AddRange(项.键);
平面。添加范围(项目);
}
返回平面;
}
公共类集合比较程序:IEqualityComparer
{
公共布尔等于(ISet x,ISet y)
{
返回x.SetEquals(y);
}
公共int GetHashCode(ISet obj)
{
未经检查
{
int hash=19;
foreach(对象中的变量foo)
{
hash=hash*31+foo.GetHashCode();
}
返回散列;
}
}
}
您能更明确地说明您真正想要发生什么吗?我可以试着从你的输出中猜出来,但并不十分清楚。什么是P和S?当你创建一个字符串的散列集时,你通常会使用一个不属于普通数据的字符进行合并,比如“P1^P2^S1^P1^S2”。你试过什么吗?我们为什么要做你的工作?构建一个循环来迭代字典并将值放入扁平化列表并不难。不管怎样,输出应该是P1、P2、S1、S2
还是P1、P2、S1、P1、S2
。当然,我已经尝试了一些方法,比如循环之类的,但这只是我目前为止所做的。它是收集字典键、比较HashSet值、求交这些值的组合……您能更明确地说明您实际希望发生什么吗?我可以试着从你的输出中猜出来,但并不十分清楚。什么是P和S?当你创建一个字符串的散列集时,你通常会使用一个不属于普通数据的字符进行合并,比如“P1^P2^S1^P1^S2”。你试过什么吗?我们为什么要做你的工作?建立一个循环来重复你的措辞并不难
public static List<string> HocusPocus(Dictionary<string, HashSet<string>> data)
{
var invert = new Dictionary<string, HashSet<string>>();
foreach (var kvp in data)
{
foreach (var s in kvp.Value)
{
if (!invert.TryGetValue(s, out var pvalues))
{
pvalues = new HashSet<string>();
invert[s] = pvalues;
}
pvalues.Add(kvp.Key);
}
}
var lookup = invert
.ToLookup(_ => _.Value, _ => _.Key, new SetComparer());
var flat = new List<string>();
foreach (var item in lookup)
{
flat.AddRange(item.Key);
flat.AddRange(item);
}
return flat;
}
public class SetComparer : IEqualityComparer<ISet<string>>
{
public bool Equals(ISet<string> x, ISet<string> y)
{
return x.SetEquals(y);
}
public int GetHashCode(ISet<string> obj)
{
unchecked
{
int hash = 19;
foreach (var foo in obj)
{
hash = hash * 31 + foo.GetHashCode();
}
return hash;
}
}
}