根据条件C#Linq删除int数组列表中的项目

cMi*_*nor -3 c# linq arrays

在C#中有一个int数组列表,如:

            List<int[]>  arrList = new List<int[]>();
            arrList.Add(new int[18] { 183, 184, 185, 186, 187, 188, 189, 190, 191, 153, 135, 117, 99, 81, 63, 45, 26, 25 });
            arrList.Add(new int[4] { 183, 209, 210, 184 });
            arrList.Add(new int[4] { 184, 210, 211, 185 });
            arrList.Add(new int[4] { 185, 211, 212, 186 });
            arrList.Add(new int[4] { 186, 212, 213, 187 });
            arrList.Add(new int[4] { 187, 213, 214, 188 });
            arrList.Add(new int[4] { 188, 214, 215, 189 });
            arrList.Add(new int[4] { 189, 215, 216, 190 });
            arrList.Add(new int[4] { 190, 216, 217, 191 });
            arrList.Add(new int[13] { 192, 191, 217, 234, 251, 268, 285, 302, 319, 349, 350, 351, 193 });
            arrList.Add(new int[17] { 194, 193, 192, 191, 217, 234, 251, 268, 285, 302, 319, 349, 350, 351, 352, 353, 195 });
            arrList.Add(new int[21] { 196, 195, 194, 193, 192, 191, 217, 234, 251, 268, 285, 302, 319, 349, 350, 351, 352, 353, 354, 355, 197 });
            arrList.Add(new int[23] { 197, 196, 195, 194, 193, 192, 191, 217, 234, 251, 268, 285, 302, 319, 349, 350, 351, 352, 353, 354, 355, 356, 198 });
Run Code Online (Sandbox Code Playgroud)

我想删除列表中已经在同一列表中的其他项目中的项目元素,但是这些项目的长度不同,所以我想保留最长的项目

如何保留这个项目

arrList.Add(new int[23]{197,196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355,356,198});
Run Code Online (Sandbox Code Playgroud)

并从同一列表中删除以下项目?

arrList.Add(new int[13]{192,191,217,234,251,268,285,302,319,349,350,351,193});
arrList.Add(new int[17]{194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,195});
arrList.Add(new int[21]{196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355,197});
Run Code Online (Sandbox Code Playgroud)

例如,问题是要删除的项目"包含"在我想要保留的项目中

        {196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355,197}
                {194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,195}
                        {192,191,217,234,251,268,285,302,319,349,350,351,193}
    {197,196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355,356,198});
Run Code Online (Sandbox Code Playgroud)

但是,要删除的项目共享一个共同的模式,它们的最后一个元素是在我想要保留的项目重复之前

编辑

我提出的一种方法是:

  1. 得到第一项,然后将其与所有项目进行比较
  2. 如果项目"包含"在项目上,则将其索引保存在列表中
  3. 循环列表包含这些项目,然后从原始列表中删除项目

但是有一个功能"包含"我可以使用吗?

我提出的其他想法是:

  1. 创建几乎是原始副本的备用列表,但最后一个元素放在第一位

例如项目

{196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355,197}
Run Code Online (Sandbox Code Playgroud)

会成为

{197,196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355}
Run Code Online (Sandbox Code Playgroud)
  1. 然后将备用列表中的每个项目与原始列表进行比较

例如:我可以比较我想要删除的项目

{197,196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355}
Run Code Online (Sandbox Code Playgroud)

我希望保留的项目

{197,196,195,194,193,192,191,217,234,251,268,285,302,319,349,350,351,352,353,354,355,356,198}
Run Code Online (Sandbox Code Playgroud)

Art*_*aca 5

一种方法,但效率不高是:

var list = arrList.Where(l1 => arrList.All(l2 => l1 == l2 || l1.Except(l2).Any()));
Run Code Online (Sandbox Code Playgroud)

在这里,您可以过滤作为另一个子集的数组arrList.您可以使用检查子集!l1.Except(l2).Any(),因此您将保留不是任何其他子集的数组.

在你的情况下,list将有长度数组4,1823.


如果每个数组中的元素都是唯一的,则可以将每个数组投影到a HashSet并使用IsSubsetOf(在最坏的情况下采用O(n + m)),以提高可以根据数组对数组进行排序的性能,Length并检查每个数组与其他数组.后者在列表中:

var hashSets = arrList.Select(l => new HashSet<int>(l))
                      .OrderBy(hs => hs.Count)
                      .ToArray();

var result = new List<HashSet<int>>();

for (int i = 0; i < hashSets.Length; i++)
{
    bool isSubset = false;
    for (int j = i + 1; j < hashSets.Length; j++)
        if (hashSets[i].IsSubsetOf(hashSets[j]))
        {
            isSubset = true;
            break;
        }

    if (!isSubset)
        result.Add(hashSets[i]);
}
Run Code Online (Sandbox Code Playgroud)

如果您需要将集合作为数组,则可以将每个集合投射HashSet<int>int[].