nichu09
nichu09

Reputation: 892

compare different type of list in c#

i have two list one is string list and other one is list of one class.that class contain some properties like soid,itemname,qty etc and its value also..string list and class list have some common property .so i wanted to check the string list with class list and add common values to one dictionary.

public class Input
   {
       public string soid { get; set; }

       public string itemname { get; set; }

       public int qty { get; set; }
   }
list<Input> inputclass=new  list<Input>();//inputclass list

List<string> metadata=new List<string>();//string list
metadata.Add("itemname");
        metadata.Add("soid");
        metadata.Add("qty");

so i wanted to compare the class member name with string list name

Upvotes: 1

Views: 991

Answers (3)

Conrad Clark
Conrad Clark

Reputation: 4526

If I understood it right, you want to compare the type itself, not the instances inside that list.

You could do it this way:

List<string> metadata = new List<string>();//string list
metadata.Add("itemname");
metadata.Add("soid");
metadata.Add("qty");
metadata.Add("yada");

var result = from str in metadata
             join prop in typeof(Input).GetProperties() on str equals prop.Name
             select str;

foreach (string prop in result)
{
    Console.WriteLine(prop);
}

Now, if you have a List of T unknown objects and want to match each with the metadata, tell me and I'll help you.

EDIT based on your comment: when we get the common name between list<input> and string how will get the value of corresponding member of the class.now you return only common names r8..?

You could do it like this. Suppose you have these two classes:

public class Input
{
    public string soid { get; set; }

    public string itemname { get; set; }

    public int qty { get; set; }
}

public class Yada : Input
{
    public string yada { get; set; }
}

So Input has 3 of the 4 properties, and Yada class has all 4.

Then suppose we have a list of objects:

List<Input> inputclass = new List<Input>();//inputclass list

inputclass.Add(new Input() { itemname = "test",soid="myId",qty=10 });
inputclass.Add(new Yada() { itemname = "test2",soid="myId2", yada = "woo",qty=20 });

You could get all the matching properties from the objects, including their current values, with this code:

var result = inputclass.Select(
                 input => (from str in metadata
                           join prop in input.GetType().GetProperties()
                           on str equals prop.Name
                           select new { Obj = input, Prop = str, Value = prop.GetValue(input, null) }))
                           .SelectMany(i => i)
                           .GroupBy(obj => obj.Obj);

foreach (var obj in result)
{
    Console.WriteLine(obj.Key);
    foreach (var prop in obj)
    {
        Console.WriteLine(prop.Prop + ":" + prop.Value);
    }
    Console.WriteLine();
 }

 Console.ReadKey();

Here is my input:

enter image description here

Just on a note, be careful when using GetValue: you'll have to do slight changes for it to work with Indexers, for example.

Upvotes: 1

sloth
sloth

Reputation: 101072

Not sure if I understood you 100% correctly, but given the following input:

var inputclass= new List<Input>() {
    new Input(){ soid="123", itemname="Bar", qty=123 },
    new Input(){ soid="777", itemname="Foo", qty=999 } 
};
List<string> metadata=new List<string>() { "itemname", "soid", "qty" };

you can use the .ToDictionary() and .GetProperty() methods like this

Type t = typeof(Input);
var result = metadata.ToDictionary(i => i, i => inputclass.Select(c => t.GetProperty(i).GetValue(c)));

to create a dictionary that will look like

enter image description here

EDIT:

If metadata can contain values that are not properties of Input, the following would be save:

var result = metadata.Select(i => t.GetProperty(i))
                     .Where(i => i != null)
                     .ToDictionary(i => i.Name, i => inputclass.Select(c => i.GetValue(c)));

Upvotes: 3

emigue
emigue

Reputation: 502

Using this ReflectionExt.GetAttr you can do something like this:

var dict = new Dictionary<string, List<string>>();

foreach(var listItem in inputclass)
{
   foreach(var metaItem in metadata)
   {
       try
       {
            var value = ReflectionExt.GetAttr(listItem, metaItem);

            if (dict[metaItem] == null)
                dict[metaItem] = new List<string>();

            if (!dict[metaItem].Contains(value)) // Add only if not exists
                dict[metaItem].Add(value);
       }
       catch
       {
           ;
       }

   }

}

Upvotes: 0

Related Questions