c# - 在两个数组中查找唯一字符串 C#

标签 c# arrays string datagridview unique

您好,我正在尝试在从 XML 文件填充的两个 dataGridView 表中查找唯一字符串。我编写的代码运行没有问题,但是当我更改其中一个表中的字符串(使其唯一)时,它无法检测到。我的逻辑有问题吗?

    private void button5_Click(object sender, EventArgs e)
    {
        string[] column1 = new string[dataGridView1.Rows.Count];
        string[] column2 = new string[dataGridView2.Rows.Count];
        int unique = 0;
        bool found = false;
        for (int i = 0; i < dataGridView1.Rows.Count; i++)
        {
            column1[i] = Convert.ToString(dataGridView1.Rows[i].Cells[2].Value);
        }
        for (int i = 0; i < dataGridView2.Rows.Count; i++)
        {
            column2[i] = Convert.ToString(dataGridView2.Rows[i].Cells[2].Value);
        }
        for (int i = 0; i < column1.Length; i++)
        {
            for (int j = 0; j < column2.Length; j++)
            {
                if (column1[i] == column2[j])
                {
                    found = true;
                }
            }
            if (found == false)
            {
                unique++;
                found = false;
            }
        }
        MessageBox.Show(unique + " unique strings found!"); 
    }

最终解决方案需要能够返回包含唯一字符串的单元格,以便我可以将它们突出显示给用户。非常感谢您的帮助!

最佳答案

使用 linq 很简单:

array1.Except(array2).Concat(array2.Except(array1))

作为对您评论的回应,您可以模拟具有两个左联接的完整外部联接,并在输出中查找空值。在另一侧不匹配的连接的任何一侧都可以被认为是唯一的。使用以下扩展进行连接:

public static class LinqEx
{
    public static IEnumerable<TResult> 
        LeftOuterJoin<TOuter, TInner, TKey, TResult>(
            this IEnumerable<TOuter> outer, 
            IEnumerable<TInner> inner, 
            Func<TOuter, TKey> outerKeySelector, 
            Func<TInner, TKey> innerKeySelector, 
            Func<TOuter, TInner, TResult> resultSelector)
    {
        return outer
            .GroupJoin(
                inner, 
                outerKeySelector, 
                innerKeySelector, 
                (a, b) => new
                {
                    a,
                    b
                })
            .SelectMany(
                x => x.b.DefaultIfEmpty(), 
                (x, b) => resultSelector(x.a, b));
    }

    public static IEnumerable<TResult> 
        FullOuterJoin<TSet1, TSet2, TKey, TResult>(
            this IEnumerable<TSet1> set1, 
            IEnumerable<TSet2> set2, 
            Func<TSet1, TKey> set1Selector, 
            Func<TSet2, TKey> set2Selector, 
            Func<TSet1, TSet2, TResult> resultSelector)
    {
        var leftJoin = set1.
            LeftOuterJoin(
                set2, 
                set1Selector, 
                set2Selector, 
                (s1, s2) => new {s1, s2});
        var rightJoin = set2
            .LeftOuterJoin(
                set1, 
                set2Selector, 
                set1Selector, 
                (s2, s1) => new {s1, s2});
        return leftJoin.Union(rightJoin)
            .Select(x => resultSelector(x.s1, x.s2));

    }
}

然后您可以创建匿名对象来捕获附加数据,例如项目的索引及其来源,并将它们外连接。连接两侧都有项目的结果被过滤掉(因为它们存在于两个集合中),因此结果集现在只包含其中一个集合唯一的项目。

void Main()
{
    var set1 = new[] {"a", "b", "c"};
    var set2 = new[] {"b", "c", "d", "d"};
    var annotatedSet1 = set1
        .Select((item,index) => new {src = "set1", index, item});
    var annotatedSet2 = set2
        .Select((item,index) => new {src = "set2", index, item});

    var uniques = annotatedSet1
        .FullOuterJoin(
            annotatedSet2, 
            x => x.item, 
            x => x.item,
            (s1, s2) => new {s1, s2})
        .Where(x => x.s1 == null || x.s2 == null)
        .Select(x => x.s1 ?? x.s2);
}

这会产生结果:

{src="set1", index=0, item="a"}
{src="set2", index=2, item="d"}
{src="set2", index=3, item="d"}

关于c# - 在两个数组中查找唯一字符串 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12074040/

相关文章:

string - 从命令行 cmd 启动 Windows 10 UWP 应用程序

java - 从字符串中提取目录

c# - 将从 .bin 文件读取的数据解码到字段中

python - 找出总和最接近给定数 N 的三个整数

c# - Quartz.net cron 触发表达式每两周一次

arrays - 查找列表中的最小数字

java - 泛型以及在实现 Iterable Interface 的类中使用新创建的方法

string - LISP - 修改字符串

c# - 任务取消异常 (ThrowForNonSuccess)

c# - 按下按钮即可播放声音