简体   繁体   English

LINQ 与 C# 中的相交方法

[英]Intersect method in LINQ with C#

I am trying to obtain the same files using Intersect method from two folders.我正在尝试使用 Intersect 方法从两个文件夹中获取相同的文件。 123.xml files are the same (no change with content, date, size) in all the folders. 123.xml 文件在所有文件夹中都是相同的(内容、日期、大小没有变化)。

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这是来自 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);

The queryCommonFiles is only returning the 123.xml from Content folder, but not the other one. queryCommonFiles 仅从 Content 文件夹返回 123.xml,而不是另一个。

This is the code from the FileCompare这是来自 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.这对于 list1 和 helo.xml 对于 list2 产生 hi.xml。 And as I said only one 123.xml for the intersect method.正如我所说,只有一个 123.xml 用于相交方法。

Any suggestions would be appreciated任何建议,将不胜感激

Thanks,谢谢,

I just changed the Equals method to achieve the desired results我只是更改了 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();
        }

    }

Everything looks OK.一切看起来都很好。 Make sure both Scores\123.xml and Power\123.xml have the same length.确保Scores\123.xmlPower\123.xml的长度相同。

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

Therefore, as far as your FileCompare class is concerned, your input collections contain duplicates.因此,就您的 FileCompare class 而言,您的输入 collections 包含重复项。 According to MSDN , Intersect evaluates distinct elements in each set.根据MSDN ,Intersect 评估每个集合中的不同元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM