-8

I am intereted in finding the values from List. I am working on Componentlist. Below are my object structure.

Public Class Component
{
   public string Type {get; set;}
   public List<ComponentDetails> Details {get; set;}
}

& my ComponentDetails structure is

Public Class ComponentDetails
{
  public string Filename {get; set;}
  public string Size {get; set;}
  public DateTime Date {get; set;}
}

I have two objects namely Source & Destination (of type List<Component>). I need to get the first item from source and find the details from destination. Objective is to find any differnecs from source to destination in terms of Size & createdDate.

In other words, using loops, get the first item from Source (i.e Name) and get what values will be there in Destination.

Question here is, how to iterate destination items to find the given filename details.

Please Help!.

Please note: Destination can be n numbers. I need to get the source item and get the details from all destinations.

Code Snippet:

    protected void btnGetComparisionResult_Click(object sender, EventArgs e)
    {
        List<Components> sourceComponents = GetSourceComponents();
        List<Components> destinationComponent = GetDestinationComponents();

        foreach (var pitem in sourceComponents) // ParentItem - Component Class
        {
            foreach (var citem in pitem.ComponentDetails) //Child Item - ComponentDetail Class
            {
        //here I need to pass "citem.Name" as input and 
                    //need to get the details from Detination.

                    //IF IT MATCHES, I NEED TO CREATE A REPORT. 
                    //ComponentName  SrcSize    SrcDate   DestSize   DestDate.
            }
        }
    }

Finaly, if source has greater size & datetime, we need to take necessary action.

BlueMoon
  • 51
  • 4
  • 13

4 Answers4

1

you get two lists of Component, one of which holds the Type property and the other holds the Details property? Anyway it sounds like you should refactor this design. If this is not possible try using IEnumerables linq methods for example:

list1.ForEach(x => list2.First(v => v.Name == x.Name));

edit

Ok, you added your code so it's clearer now. Really it doesn't sound as if you need the Component class at all here. You should refactor IMO. Something like this:

protected void btnGetComparisionResult_Click(object sender, EventArgs e) {
    Dictionary<string, ComponentDetails> sourceComponentsDetails //key is component name
      = GetSourceComponentDetails();
    Dictionary<string, ComponentDetails> destinationComponentDetails //key is component name
      = GetDestinationComponentsDetials();

    foreach(string name in sourceComponentsDetails.Keys) {
        if(destinationComponentDetails.Contains(name)) {
            // create report here with name, sourceComponentsDetails[name].Size,
            // sourceComponentsDetails[name].Date, destinationComponentDetails[name].Size
            // and destinationComponentDetails[name].Date
        }
    }

If you can't refactor, or don't want to, linq is concise and as performant as foreach. I saw several people answered wth linq examples so you should look at that.

Assaf
  • 1,352
  • 10
  • 19
0

I couldn't test my answer because I don't have any data, but this should work. You can do whatever you want with the extracted information instead of printing it.

    List<Component> Source = new List<Component>();
    List<Component> Destination = new List<Component>();

    foreach (Component c in Destination)
    {
        Console.WriteLine(c.Details);
    }
Nischaal Cooray
  • 210
  • 2
  • 12
  • Hi, I would prefer Linq query, as the no of items in both Source & destination would be more than 25k. So instead of looping all the 25K records for single SourceItem, then this would lead a performance issue. – BlueMoon Sep 19 '14 at 18:34
  • @BlueMoon: What do you think linq is going to do? It's not magic. It has to loop over collections too. – Matt Burland Sep 19 '14 at 18:35
  • You should check out [this link](http://stackoverflow.com/questions/1509442/c-linq-style-for-each). – Nischaal Cooray Sep 19 '14 at 18:37
  • @BlueMoon I COULD be wrong, But in these situations foreach loops are arguably faster, since Linq will be doing this same thing anyways. Linq just allows for simpler syntax. – psoshmo Sep 19 '14 at 18:45
0

Something like this:

    var matched = from s in source
        join d in destination on s.Type equals d.Type
        select d;

Will join your source and destination on matching Type properties and select the object from destination

If you need both the source and destination objects (so you can compare details), you could:

    var matched = from s in source
        join d in destination on s.Type equals d.Type
        select new { s, d };

If you want to make it a left join (so all records in source are returned even if they don't have an match in destination) then you could do:

    var matched = from s in source
        join d in destination on s.Type equals d.Type into tmp
        from t in tmp.DefaultIfEmpty()
        select new { s, d = t };

Here's an example: https://dotnetfiddle.net/J7iDmJ

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • Hi Matt, both source & destination has same set of values. Say Type A, Type B, Type C. So matching with Type may help us to filter the records from 25K to 7-8K records. – BlueMoon Sep 19 '14 at 18:41
  • @BlueMoon: Ok...that's what this is actually doing. It's matching them by type. That's what `s.Type equals d.Type` means. – Matt Burland Sep 19 '14 at 18:45
  • Yes this help me to filter the records but what I want is individual file details like Size, Date from both Source & destination. I have added code snippet in my question. hope that will help you to understand my problem. – BlueMoon Sep 19 '14 at 18:50
  • @BlueMoon: Yeah, and they are right there in `s` and `d` (feel free to chose better names). Your question doesn't make any sense. You are looping through the `Details` in `source` but there is no indication of how you are going to match them to the `Details` in `destination`. I guess just by index? In which case, just a simple `for` loop would work. – Matt Burland Sep 19 '14 at 18:54
  • that what I am asking, what would be better way to iterate `Destination`? We need to search the whole items from `Destination` by passing source name. I am seeking help from experts how to handle this? – BlueMoon Sep 19 '14 at 18:58
  • @BlueMoon: But you haven't said how they are matched in the first place. What is `source name` and what's it supposed to match in `Destination`? `ComponentDetails` has `Filename`, `Size` and `Date`. `Component` just has `Type` and `Details`. – Matt Burland Sep 19 '14 at 19:02
  • Hi Matt, source contains TFS details. Destination contains FTP details (say test server, qa server). Considering source (aka TFS) as base am trying to compare the files in FTP. As we are having many audio video, images file, manual verification takes more time. so am trying to automate this process. Taking items one by one from each category get the details (name, file size, created date) from TFS and comparing against Ftp. If ftp file has lesser size or older date we will conclude that file in ftp is older file and it has to replaced with TFS object. – BlueMoon Sep 19 '14 at 19:19
0

Here is an 'old school' loop method for searching through all the items:

public static void GenericTester()
{
    var source = GetSourceComponents();
    var destination = GetDestinationComponents();

    // Go through each source item
    foreach (var srcItem in source)
    {
        // And for each source, look through each destination item
        foreach (var dstItem in destination)
        {
            // See if the destination has the same Type as the source
            if (srcItem.Type == dstItem.Type)
            {
                // source and destination are the same type, so examine file details
                foreach (var srcDetail in srcItem.Details)
                {
                    foreach (var dstDetail in dstItem.Details)
                    {
                        // See if destination detail has a filename that matches the source detail filename
                        if (srcDetail.Filename == dstDetail.Filename)
                        {
                            // Do some comparison between the source.ComponentDetail 
                            // and destination.ComponentDetail here:
                            // . . .

                            break;
                        }
                    }
                }

                break;
            }
        }
    }
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43