1

I have 2 list, first one is a string list which I fill with Directory.GetFiles() method and my second list is a custom one. I have only 2 fields in my custom list. First one is FilePath second is UniqueID.. What I try to achieve is, I want to compare the string list with my custom list's FilePath field. I need to get the changes.

I've convert my Custom list to string and tried this solution Difference between two lists It worked perfect but in my case it's useless for me. I need to compare different type of lists

Here is my custom class that I'm using as model

public class IndexerListModel
{
    public string FilePath = string.Empty;
    public string uniqueID = string.Empty;
}

And this is how I tried it already

List<IndexerListModel> T3 = XMLList.Except(WinFileList, new PathComparer()).ToList();

But because I don't use the same type on my list's it did not worked.

I was expecting to get the difference like a new list that show me these "x" items inside your list have different Filepaths..

My overall goal is getting the changes in a windows folder on Application start. So I will know which files has been added/removed/changed/renamed while my application was not up

Maciej S.
  • 752
  • 10
  • 22
Shino Lex
  • 487
  • 6
  • 22
  • 1
    `var differentFilePaths = customList.Where(c => !stringList.Contains(c.FilePath));` – SᴇM Jan 23 '19 at 12:07
  • 3
    You can use `Select` to project the string property that you want to compare. Then `Except` works but you get a `List`. Otherwise you could use this approach: `XMLList.Where(x => !WinFileList.Contains(x.FilePath)).ToList()` – Tim Schmelter Jan 23 '19 at 12:08
  • List differentFilePaths = XMLList.Where(c => !WinFileList.Contains(c.FilePath)).ToList(); this gave me the list of deleted files which I should delete from my XML too to keep it updated. and if I remove the "!" which gives me the list that I should check carefully if the contect of the file changed so far okay, how can I get the list for files that has been added? – Shino Lex Jan 23 '19 at 12:28

3 Answers3

2

If I understand the problem correctly the custom <List<IndexerListModel> will contain the content of a directory Eg C:\Windows .

We will then use var myPathList = Directory.GetFiles(@"C:\Windows").ToList(); to retrieve the content of a C:\Windows when the application starts.

The result would be a list of paths that is not contained in our custom <List<IndexerListModel>

If the above assumption is correct I have come up with this solution:

public class IndexerListModel
{
    public string UniqueID { get; set; }
    public string FilePath { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var myPathList = Directory.GetFiles(@"C:\Windows").ToList();

        List<IndexerListModel> myModelList = new List<IndexerListModel> {
            new IndexerListModel {
            UniqueID= "0001",
            FilePath = @"C:\Windows\bfsvc.exe"
        },
            new IndexerListModel {
            UniqueID= "0002",
            FilePath = @"C:\Windows\diagwrn.xml"
        }
        };

        var result = myPathList.Where(path => !myModelList.Any(model => model.FilePath == path)).ToList();
    }
}

When I run the application I have a total of 27 files in my C:\Windows. - result will evaluate to a List of 25 items. That implies that a total of 25 files have been added since last execution.

We can update List myModelList in order to reflect the changes in C:\Windows. I would imagine that myModelList be saved in a db or file in order to be persistent.

Miroslav Mikus
  • 486
  • 4
  • 12
Alex Leo
  • 2,781
  • 2
  • 13
  • 29
  • Yes thank you that was the other half I needed to complete what I try to achieve. With that result variable I can get the files that has been add to folder while my application was not open. And for the other half I used List UniqueIDCheckList = XMLList.Where(c => !WinFileList.Contains(c.FilePath)).Reverse().ToList(); which gives me the list of deleted files. Now I can update my XML file everytime when my application starts correctly, thank you – Shino Lex Jan 24 '19 at 06:17
1

Use a left outer join

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


namespace ConsoleApplication98
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> WinFileList = Directory.GetFiles("AllDirectories[i]", ".", SearchOption.AllDirectories).ToList();
            List<IndexerListModel> models = new List<IndexerListModel>();

            //use left outer join
            var results = (from w in WinFileList
                           join m in models on w equals m.FilePath into wm
                           from m in wm.DefaultIfEmpty()
                           select new { model = m, windFileList = w }).ToList();


        }
    }
    public class IndexerListModel : IEqualityComparer<IndexerListModel>
    {
        public string FilePath = string.Empty;
        public string uniqueID = string.Empty;
    }

}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • If I change my class as you say will I be able to use Except to get differences between my Custom type list and my string type list? – Shino Lex Jan 23 '19 at 12:39
  • My code is verifying two properties FilePath and uniqueID while the code posted was only testing one property. I do not know what format your string list looks like. I would think you need to make it a class. – jdweng Jan 23 '19 at 13:32
  • This is how I fill my string list WinFileList = Directory.GetFiles(AllDirectories[i], "*.*", SearchOption.AllDirectories).ToList(); – Shino Lex Jan 23 '19 at 13:35
1

models.Except(models.Where(y=> strings.Contains(y.FilePath)));