LINQ 与 C# 中的相交方法

发布于 2024-11-17 17:09:35 字数 2792 浏览 8 评论 0原文

我正在尝试使用相交方法从两个文件夹中获取相同的文件。 所有文件夹中的 123.xml 文件都是相同的(内容、日期、大小没有变化)。

Scores\Content\123.xml
Scores\Content\hi.xml
Scores\123.xml

Power\Content\123.xml
Power\Content\helo.xml
Power\123.xml

这是来自 C# 代码

        System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(path1);
        System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(path2);

        IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
        IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

        FileCompare myFileCompare = new FileCompare();

        bool areIdentical = list1.SequenceEqual(list2, myFileCompare);

        if (areIdentical == true)
        {
            Console.WriteLine("the two folders are the same");
        }
        else
        {
            Console.WriteLine("The two folders are not the same");
        }


        var queryCommonFiles = list1.Intersect(list2, myFileCompare);

queryCommonFiles 仅从 Content 文件夹返回 123.xml,而不返回另一个。

这是来自 FileCompare 编辑的代码

class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{

    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        return (f1.Name == f2.Name &&
                f1.Length == f2.Length);
    }

    // Return a hash that reflects the comparison criteria. According to the 
    // rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
    // also be equal. Because equality as defined here is a simple value equality, not
    // reference identity, it is possible that two or more objects will produce the same
    // hash code.
    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }

}

var queryList1Only = (from file in list1
                                  select file).Except(list2, myFileCompare);

            Console.WriteLine("The following files are in list1 but not list2:\n");
            foreach (var v in queryList1Only)
            {
                Console.WriteLine(v.FullName);
            }


            var queryList2Only = (from file in list2
                                  select file).Except(list1, myFileCompare);

            Console.WriteLine("The following files are in list2 but not list1:\n");
            foreach (var v in queryList2Only)
            {
                Console.WriteLine(v.FullName);
            }

这会生成 list1 的 hi.xml 和 list2 的 helo.xml。正如我所说,相交方法只有一个 123.xml。

任何建议将不胜感激

谢谢,

I am trying to obtain the same files using Intersect method from two folders.
123.xml files are the same (no change with content, date, size) in all the folders.

Scores\Content\123.xml
Scores\Content\hi.xml
Scores\123.xml

Power\Content\123.xml
Power\Content\helo.xml
Power\123.xml

This is from the C# code

        System.IO.DirectoryInfo dir1 = new System.IO.DirectoryInfo(path1);
        System.IO.DirectoryInfo dir2 = new System.IO.DirectoryInfo(path2);

        IEnumerable<System.IO.FileInfo> list1 = dir1.GetFiles("*.*", System.IO.SearchOption.AllDirectories);
        IEnumerable<System.IO.FileInfo> list2 = dir2.GetFiles("*.*", System.IO.SearchOption.AllDirectories);

        FileCompare myFileCompare = new FileCompare();

        bool areIdentical = list1.SequenceEqual(list2, myFileCompare);

        if (areIdentical == true)
        {
            Console.WriteLine("the two folders are the same");
        }
        else
        {
            Console.WriteLine("The two folders are not the same");
        }


        var queryCommonFiles = list1.Intersect(list2, myFileCompare);

The queryCommonFiles is only returning the 123.xml from Content folder, but not the other one.

This is the code from the FileCompare

class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
{

    public FileCompare() { }

    public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
    {
        return (f1.Name == f2.Name &&
                f1.Length == f2.Length);
    }

    // Return a hash that reflects the comparison criteria. According to the 
    // rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
    // also be equal. Because equality as defined here is a simple value equality, not
    // reference identity, it is possible that two or more objects will produce the same
    // hash code.
    public int GetHashCode(System.IO.FileInfo fi)
    {
        string s = String.Format("{0}{1}", fi.Name, fi.Length);
        return s.GetHashCode();
    }

}

EDIT:

var queryList1Only = (from file in list1
                                  select file).Except(list2, myFileCompare);

            Console.WriteLine("The following files are in list1 but not list2:\n");
            foreach (var v in queryList1Only)
            {
                Console.WriteLine(v.FullName);
            }


            var queryList2Only = (from file in list2
                                  select file).Except(list1, myFileCompare);

            Console.WriteLine("The following files are in list2 but not list1:\n");
            foreach (var v in queryList2Only)
            {
                Console.WriteLine(v.FullName);
            }

This produces as hi.xml for list1 and helo.xml for list2. And as I said only one 123.xml for the intersect method.

Any suggestions would be appreciated

Thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

合久必婚 2024-11-24 17:09:35

我只是改变了Equals方法来达到想要的结果

class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
    {

        public FileCompare() { }

        public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
        {
            return (f1.Name == f2.Name && f1.Directory.Name == f2.Directory.Name && 
                    f1.Length == f2.Length);
        }

        // Return a hash that reflects the comparison criteria. According to the 
        // rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
        // also be equal. Because equality as defined here is a simple value equality, not
        // reference identity, it is possible that two or more objects will produce the same
        // hash code.
        public int GetHashCode(System.IO.FileInfo fi)
        {
            string s = String.Format("{0}{1}", fi.Name, fi.Length);
            return s.GetHashCode();
        }

    }

I just changed the Equals method to achieve the desired results

class FileCompare : System.Collections.Generic.IEqualityComparer<System.IO.FileInfo>
    {

        public FileCompare() { }

        public bool Equals(System.IO.FileInfo f1, System.IO.FileInfo f2)
        {
            return (f1.Name == f2.Name && f1.Directory.Name == f2.Directory.Name && 
                    f1.Length == f2.Length);
        }

        // Return a hash that reflects the comparison criteria. According to the 
        // rules for IEqualityComparer<T>, if Equals is true, then the hash codes must
        // also be equal. Because equality as defined here is a simple value equality, not
        // reference identity, it is possible that two or more objects will produce the same
        // hash code.
        public int GetHashCode(System.IO.FileInfo fi)
        {
            string s = String.Format("{0}{1}", fi.Name, fi.Length);
            return s.GetHashCode();
        }

    }
蓝色星空 2024-11-24 17:09:35

一切看起来都不错。确保 Scores\123.xmlPower\123.xml 具有相同的长度。

Everything looks OK. Make sure both Scores\123.xml and Power\123.xml have the same length.

庆幸我还是我 2024-11-24 17:09:35

因为您仅使用 FileInfo.Name 和 FileInfo.Length 进行比较,所以 Content\123.xml 与 123.xml 相同(假设两个文件具有相同的大小,我猜测您的测试数据就是这种情况)。

因此,就您的 FileCompare 类而言,您的输入集合包含重复项。根据 MSDN,Intersect 评估不同元素在每组中。

Because you only compare using FileInfo.Name and FileInfo.Length, Content\123.xml is the same as 123.xml (assuming both files have the same size, which I'm guessing is the case for your test data).

Therefore, as far as your FileCompare class is concerned, your input collections contain duplicates. According to MSDN, Intersect evaluates distinct elements in each set.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文