2012-07-25 146 views
0

现状:LINQ的扩展集操作

HashSet<string> MasterSet => {100, 3}

HashSet <string> SubSet => {100, 3} or {100} or {100, 3, 1}

所以从子集的巨大的名单,根据MasterSet我选择特定的设置是这样的:

if(MasterSet.SetEquals(subSet) || MasterSet.IsSupersetOf(subSet) || MasterSet.IsSubsetOf(subSet))

用tha t subSet如果为真,则循环其他可用集合。

问题的重复: 如果业务逻辑要包括在主设置重复和其子集,如:

MasterSet => {100, 3, 3}

SubSet => {100, 3, 3} or {100, 3} or {100, 3, 3, 1}

然后HashSet的使用被剥夺。

如何选择的子集,如果我改变MasterSet和子集List<string>

编辑:由“BigYellowCactus”提供 解决方案的工作。但是,如果我想使用标题而不是元素的顺序来匹配,那么过滤集合会更容易?

MasterSet => {100, 3, 4} 
MasterHeaders => {"T","F","V"} //Headers element corresponds to the MasterSet element 

案例1:

SubSet => {3, 100} 
SubSetHeaders => {"F", "T"} //Headers element corresponds to the SubSet element 

案例2:

SubSet => {4, 3} 
SubSetHeaders => {"V", "F"} //Headers element corresponds to the SubSet element 

是否有可能通过值进行比较MasterHeaders和SubSetHeaders然后Match头第一场比赛?

+0

是你的问题,“是否存在允许重复成员的ISet 的实施?”据我了解,这是你的问题,对吗? – Jodrell 2012-07-25 10:47:42

+0

我正在使用.NET 3.5 :-( – Suresh 2012-07-25 10:50:34

回答

1

您可以使用All扩展方法。

说明

确定序列中的所有元素是否满足条件。


实施例:

if (MasterSet.All(e => SubSet.Contains(e)) || SubSet.All(e => MasterSet.Contains(e))) 
{ 
    //do stuff 
} 

备选:

if (!MasterSet.Except(SubSet).Any() || !SubSet.Except(MasterSet).Any()) 
{ 
    //do stuff 
} 

编辑:

只是为了要SubSet { 100, 3, 3 }比赛MasterSet = { 100, 100, 3 }铱星在他的评论中指出的情况下,你可以通过简单的计算每个元素的出现去。

if (MasterSet.All(e => MasterSet.Count(r => r==e) <= SubSet.Count(r => r==e)) 
    || SubSet.All(e => SubSet.Count(r => r==e) <= MasterSet.Count(r => r==e))) 
{ 
    //do stuff 
} 

(请注意,这可能不是最有效的方式......)


EDIT2:

既然你基本上搜索序列内的序列,就可以使用以下方法:

void Main() 
{ 
    var MasterSet = new List<string>() {"100", "3","4"}; 

    var SubSets = new[] 
    { 
     new List<string>() {"100", "100", "3"}, 
     new List<string>() {"100", "3", "4"}, 
     new List<string>() {"32", "3423", "4234", "100", "3", "4", "34234"}, 
     new List<string>() {"100", "32", "3423", "4234", "100", "3", "4", "34234"}, 
     new List<string>() {"100", "32", "3", "4234", "100", "4", "34234"}, 
     new List<string>() {"100", "4", "3"}, 
     new List<string>() {"100", "3", "3"}, 
     new List<string>() {"100", "3"}, 
     new List<string>() {"100", "3", "3", "1"} 
    }; 

    foreach (var SubSet in SubSets) 
    { 
     if (IsMatch(MasterSet, SubSet)) 
      Console.WriteLine(String.Join(", ", SubSet) + " is a \"subset\""); 
     else if (IsMatch(SubSet, MasterSet)) 
      Console.WriteLine(String.Join(", ", SubSet) + " is a \"superset\""); 
    } 
} 

bool IsMatch<T>(IEnumerable<T> source, IEnumerable<T> to_test) 
{ 
    using (var enumerator = source.GetEnumerator()) 
    using (var sub_enumerator = to_test.GetEnumerator()) 
     while (sub_enumerator.MoveNext()) 
     { 
      if (!enumerator.MoveNext()) 
       return false; 
      if (!enumerator.Current.Equals(sub_enumerator.Current)) 
       sub_enumerator.Reset(); 
     } 
    return true; 
} 

输出:

100,图3,图4是一个 “子集”
32,3423,4234,100,3,4,34234是一个 “超集”
100,32,3423,4234, 100,3,4,34234是一个 “超集”
100,图3是一个 “子集”

+0

谢谢,我会尝试将它标记为答案,如果成功。 – Suresh 2012-07-25 11:01:16

+0

如果我正确理解了这个意图,如果说MasterSet = {100,100,3}和SubSet是{100,3,3},那么这将错误地返回true - 而SubSet中的所有元素都存在于MasterSet中并且副作用相反,MasterSet既不是超集也不是SubSet的子集(至少给出了我期望的那些具有不必要唯一元素的操作的定义)。 – Iridium 2012-07-25 11:06:38

+0

如果这是他想要或不想要的,这必须由Suresh来回答,因为严格地说'100','100','3'的集合是'100','3',而集合'100', '3','3'也是'100','3' .... – sloth 2012-07-25 11:13:49

0

ISet<T>当前框架的实现是HashSet<T>SortedSet<T>。这两个类都强制成员唯一性并且不允许重复。

虽然这可能首先看起来像框架中的遗漏,但它实际上与数学集的属性和定义有关。正如this post解释,数学集没有重复成员和logicaly {100, 3}相当于{100, 3, 3}.

它可能会延长List<T>实施ISet<T>,也许还称新类Sack<T>但非唯一实施0​​的将比那些在框架中存在的人更具挑战性,但没有太多的考虑,似乎一般Knapsack problems的回忆。