【问题标题】:How do I delete all elements in an int array that exist in another int array?如何删除一个 int 数组中存在于另一个 int 数组中的所有元素?
【发布时间】:2017-12-13 07:28:58
【问题描述】:

在我的 C# 程序中,我有一个 int 数组,其中包含一组整数,并且偶尔会出现这些整数的副本。我想创建一个数组,该数组仅包含初始数组中作为重复项存在的数字,但其本身不包含重复项。根据我对 C# 的新手理解,我认为以下代码可以解决问题:

int a = 9;
int b = 6;
int c = 3;
int index = 0;

int[] mltpls = new int[a + b + c];

while (a > 0)
{
    mltpls[index] = 2 * a;
    a -= 1;
    index += 1;
}

while(b > 0)
{
    mltpls[index] = 3 * b;
    b -= 1;
    index += 1;
}

while(c > 0)
{
    mltpls[index] = 5 * c;
    c -= 1;
    index += 1;
}

int[] mltpls_unique = mltpls.Distinct().ToArray();
int[] mltpls_dplcts = mltpls.Except(mltpls_unique).ToArray();

Console.WriteLine(mltpls_dplcts);

//EDIT

//By running the following code I can write out all numbers in "mltpls"
for (int i = 0; i < mltpls.Length; i++)
{
 Console.Write(mltpls[i] + ", ");
}

/*If I try to run equivalent code for the "mltpls_dplcts" array nothing
only a blank line is displayed.*/

当我运行这个目标时,我的控制台应用程序的最终结果是一个空白行。我对此的解释是数组 mltpls_dplcts 是空的,或者我错误地要打印数组。

如何只从数组中获取重复值?

【问题讨论】:

  • 可以添加输入数组内容吗?从代码中很难估计该数组中的真正内容。
  • 使用 List 比使用数组更好。
  • @PMF 名为“mltpls”的数组的数组输入为:18, 16, 14, 12, 10, 8, 6, 4, 2, 18, 15, 12, 9, 6, 3、15、10、5
  • "如何在 C# 中删除另一个 int 数组中存在的 int 数组中的所有元素?"这个问题具有误导性。如果您删除 mltpls 中存在于 mltpls_unique 中的所有元素,则将它们全部删除!这实际上就是你所做的。但似乎您希望将重复项挑出到一个新数组中

标签: c# arrays


【解决方案1】:

我对此的解释是数组 mltpls_dplcts 是空的,或者我错误地要打印数组。

两种解释都是正确的

Distinct 将返回在mltps 中至少出现一次的每个项目。如果您现在申请Except,您将一无所获,因为mltpls_unique 中的所有项目也存在于mltps 中。数组中的项目按值进行比较,因此对于Except,一个数字是否在另一个数组中出现多次并不重要。如果它存在一次,它将不会返回数字。所以你得到一个空数组。

此外,您不能简单地将整个数组推入Console.WriteLine。使用循环或String.Join 打印内容:

Console.WriteLine(String.Join(" ",mltpls_dplcts));

解决方案:您可以使用良好的旧循环方法来解决它;)

int[] mltpls_unique = mltpls.Distinct().ToArray();
// The amount of duplicates is the difference between the original and the unique array
int[] mltpls_dplcts = new int[mltpls.Length-mltpls_unique.Length];


int dupCount = 0;
for (int i = 0; i < mltpls.Length; i++)
{
    for (int j = i+1; j < mltpls.Length; j++)
    {
        if (mltpls[i] == mltpls[j])
        {
            mltpls_dplcts[dupCount] = mltpls[i];
            dupCount++;
        }
    }
}

输出:18 12 10 6 15

【讨论】:

  • @Mong_Zhu 我明白上面的代码解决了问题。但是,我不完全理解它是如何运作的,或者我需要通过什么想法来想出它。具体来说,我不明白在 for 循环中使用 for 循环如何帮助我们生成寻求的相等性。
  • @K.Claesson 想想如果将它们写在一张纸上,你将如何识别它们。您会记住第一个数字并扫描列表以再次找到它。您将开始查看已记住项目的右侧位置(因为您不想将该项目与其自身进行比较)IF 您会找到将其写在另一张纸上的数字,否则您知道它是独特的。现在你取出列表中的第二个元素,记住它并重新开始扫描。您的问题是使用循环的示例。如果您有更多问题,请不要犹豫:)
  • @K.Claesson 想象一下,您将左 index 手指放在您尝试记住的第一个数字上,然后用右手 index寻找副本。现在您的手指作为指针或 indexers 工作,这基本上也是在 2 个循环 i 和 @987654333 中使用 index 变量(它们甚至被称为这种方式) @。每次移动右手手指时,您都会回头看左手指指向的位置并比较数字,然后将右手手指向前移动一个位置:) 这可以理解吗?
  • @Mong_Zhu 是的,您的类比非常棒,可以帮助我解释代码并理解其背后的思维过程。两个问题:i) 我们之所以可以说第一个,也就是第二个,for 循环应该在 i &lt; mltpls.Length 时执行,因为 mltpls.Length = x 而最后一个索引 mltpls 是 x - 1,因为索引从 0 开始? ii) 根据我对代码的解释,如果一个数字在 mltpls 中出现 n 次,则 mltpls_dplcts 将包含该数字 n - 1 次。这是正确的吗?
  • @K.Claesson i) "而最后一个索引 mltpls 是 x - 1,因为索引从 0 开始?"是的。您也可以只运行第一个循环直到mltpls.Length-1,因为不需要比较最后一个元素,因为没有其他元素跟随它。 ii) 这是正确的,因为它只计算正面比较。这就是为什么不存在唯一元素并且它们的计数是0
【解决方案2】:

您不能直接打印数组。你需要一个一个循环打印:

foreach (var element in mltpls_dplcts)
{
    Console.WriteLine(element);
}

【讨论】:

    【解决方案3】:

    你可以像这样得到不同重复的数组:

    var duplicates = mltpls.GroupBy(o => o)
        .Where(g => g.Count() > 1)
        .Select(g => g.First()).ToArray();
    

    要获取仅包含原始数组中不在第二个数组中的元素的新数组,您可以使用:

    var newArr = mltpls.Except(duplicates).ToArray();
    

    【讨论】:

      【解决方案4】:

      查找重复项不是正确的方法。您可以使用GroupBy 确定重复项并将它们打印到控制台,如下所示;

              var mltpls_dplcts = mltpls.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key).ToArray();
              foreach (var duplicate in mltpls_dplcts)
              {
                  Console.WriteLine(duplicate);
              }
      

      另外,如果你不是必须使用Array,我建议你使用List&lt;int&gt;

      【讨论】:

        【解决方案5】:

        来自 OP 的更新问题:

        如何只从数组中获取重复值?

        var arr1 = new[] {1, 2, 4, 4, 5, 5, 5, 5, 6, 7, 1};
        var duplicates = arr1.ToLookup(_ => _, _ => _).Where(_ => _.Count()>1).Select(_ => _.Key).ToArray();
        // duplicates is now { 1, 4, 5 }
        

        来自 OP 的原始问题:

        如何在 C# 中删除一个 int 数组中存在于另一个 int 数组中的所有元素?

        var arr1 = new[] {1, 2, 4, 5, 6, 7};
        var arr2 = new[] {4, 5};
        
        var hash = new HashSet<int>(arr1);
        hash.ExceptWith(arr2);
        var filteredArray = hash.ToArray();
        
        // filteredArray is now { 1, 2, 6, 7 }
        

        【讨论】:

        • 不幸的是,您的示例与帖子中的示例不匹配。您的输入需要如下所示:var arr1 = new[] { 1, 2, 4, 2, 5, 1, 4 };var arr2 = new[] { 1, 2, 4, 5 }; 使用您的方法,您将获得与 OP 相同的结果。
        • 我看到 OP 已经编辑了这个问题。 :-( 我回答“如何删除一个 int 数组中存在于 C# 中另一个 int 数组中的所有元素?”,但现在这个问题已经改写了。
        • 我猜这个问题具有误导性,因为他描述的情况与假设的问题不同。我编辑并改写了这个问题。他在帖子中将目标描述为“我想创建一个仅包含初始数组中作为重复项存在的数字的数组”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-11
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        • 2020-12-04
        • 2021-11-20
        相关资源
        最近更新 更多