How to make nested foreach loop method generic - c#

I want to get a list of all (unique) Apple (or Oranges) objects:
var theBigFruitsList = new List<Fruits>{
new Fruits(){
Apples = new List<Apple>{
new Apple { Id = 1 },
new Apple { Id = 2 }
}
},
Oranges = new List<Orange>{
new Orange { Id = 4 },
new Orange { Id = 5 }
}
},
FruitBoolean = False,
FruitCount = 4,
},
new Fruits(){
Apples = new List<Apple>{
new Apple { Id = 3 },
new Apple { Id = 1 },
}
},
Oranges = new List<Orange>{
new Orange { Id = 6 },
}
}
FruitBoolean = False,
FruitCount = 3,
}
}
I have written this method for it:
public static List<Apple> GetApplesFromBigFruitsList(List<Fruits> theBigFruitsList )
{
var dc = new Dictionary<long, Apple>();
foreach (var fruits in theBigFruitsList)
{
foreach (var apple in fruits.Apples)
{
if (!dc.ContainsKey(apple.Id))
dc.Add(apple.Id, apple);
}
}
return dc.Values.ToList();
}
But as besides Apples and Oranges there are many other types of 'Fruits' in that object, I have that method more then 10 times where the word Apple is just replaced with Orange.. It would make sense to make it generic.
I wrote this function but it gives an error as Fruits class does not implement an enumerator. Please help!
public static List<T> FilterFruits<T>(T typeToGet, List<Fruits> theBigFruitsList)
{
List<T> fruitResult = new List<T>();
var fruitType = typeToGet.GetType();
foreach (var fruits in theBigFruitsList)
{
foreach (var fruit in fruits) //errors, intention is to loop over all properties in the Fruits entity to find one specific type
if (fruit.GetType() == fruitType) //check if type is Apple
{
fruitResult.AddRange(fruits); //add the Apples to a list
}
}
return fruitResult;
}
The classes:
public class Fruits{
public List<Apple> Apples { get; set; }
public List<Orange> Oranges { get; set; }
public List<Pineapple> Pineapples { get; set; }
public List<Mango> Mangos { get; set; }
public bool FruitBoolean { get; set; }
public long FruitCount { get; set; }
}
public class Apple{
public long Id { get; set; }
}
public class Orange{
public long Id { get; set; }
}
public class Pineapple{
public long Id { get; set; }
}
public class Mango{
public long Id { get; set; }
}
The desired method result:
var Apples = List<Apple>{
new Apple { Id = 1 },
new Apple { Id = 2 },
new Apple { Id = 3 }
}

With One Big List
Storing each type of fruit in its own separate list is...weird. I suggest you combine them in a single list. If you can't change the design, you can combine them at run time like this:
IEnumerable<object> GetAllFruits(Fruits bigFruitlist)
{
return ((IEnumerable<object>)bigFruitlist.Apples)
.Concat((IEnumerable<object>)bigFruitlist.Oranges)
.Concat((IEnumerable<object>)bigFruitlist.Mangoes)
.Concat((IEnumerable<object>)bigFruitlist.Pineapples);
}
Of course it would be way better if all of your fruits had a common interface-- then you wouldn't need IEnumerable<object>-- but this can still work if you can't make that change either.
Once you have the combined list, the rest is easy:
List<T> FilterFruits<T>(Fruits bigFruitlist)
{
return GetAllFruits(bigFruitList).OfType<T>().ToList();
}
With an Array of Lists
If there is some reason you want to avoid enumerating all of the lists (i.e. the lists are massive and performance is a concern), you can also do it with an array of lists.
object[] GetAllFruitLists(Fruits bigFruitlist)
{
return new object[]
{
bigFruitlist.Apples,
bigFruitlist.Oranges,
bigFruitlist.Mangoes,
bigFruitlist.Pineapples
};
}
List<T> FilterFruits<T>(Fruits bigFruitlist)
{
return GetAllFruitLists(bigFruitList).OfType<List<T>>().Single();
}

To interrogate an object's type at runtime use Reflection. Like this:
public static List<T> FilterFruits<T>(List<Fruits> fruitsList) where T : IFruit
{
List<T> fruitResult = new List<T>();
var fruitType = typeof(T);
foreach (var fruits in fruitsList)
{
foreach (var fp in typeof(Fruits).GetProperties())
{
if (fp.PropertyType == typeof(List<T>)) //check if type is Apple
{
fruitResult.AddRange((List<T>)(object)fp.GetValue(fruits)); //add the Apples to a list
}
}
}
return fruitResult;
}
(T)(object)o is the C# idiom for performing a cast that can't by verified by the compiler, and may possibly fail at runtime, which we know that it won't but the compiler can't because it doesn't understand Reflection.
To do this without Reflection (which can be too slow for some scenarios), you can do something like this:
public static List<T> GetDistinct<T>( IEnumerable<Fruits> fruitsList) where T : IFruit
{
var ft = typeof(T);
Func<Fruits, List<T>> picker;
if (ft == typeof(Apple))
{
picker = (fruits) => (List<T>)(object)fruits.Apples;
}
else if (ft == typeof(Mango))
{
picker = (fruits) => (List<T>)(object)fruits.Mangos;
}
else
{
throw new NotImplementedException($"Fruit Type {ft.Name} not supported");
}
var rv = new Dictionary<long, T>();
foreach (var t in fruitsList.SelectMany(picker))
{
if (!rv.ContainsKey(t.Id))
{
rv.Add(t.Id, t);
}
}
return rv.Values.ToList();
}

Related

How can I use LINQ to retrieve entries that contain more than one property of a list within a list?

I have a List of IJapaneseDictionaryEntry objects which are described below. Inside this are IKanji objects that contain Priorites objects.
I have a rather difficult thing I would like to do and would appreciate any advice / suggestions. What I would like to do is to retrieve entries that have an entry that have Priority of "Frequency1" have Priority of "Frequency2" or Priority of "Frequency3" from the list entries that I created.
public interface IJapaneseDictionaryEntry
{
int Sequence { get; }
IEnumerable<IKanji> Kanjis { get; }
IEnumerable<IReading> Readings { get; }
IEnumerable<ISense> Senses { get; }
}
Where each object contains a list of IKanji objects
public interface IKanji
{
string Text { get; }
IEnumerable<KanjiInformation> Informations { get; }
IEnumerable<Priority> Priorities { get; }
}
Here's the list:
List<IJapaneseDictionaryEntry> entries = dictionary.GetEntries().ToList();
Here's a view that I think might help explain the contents:
I hope the information here is enough as it seems difficult to explain what I need to retrieve.
var result = entries.Where(e => e.Kanjis.Any(k => k.Priorities.Contains(Priority.Frequency1) ||
k.Priorities.Contains(Priority.Frequency2) ||
k.Priorities.Contains(Priority.Frequency3)
)).ToList();
Considering your 2 questions, I would have made something like this:
[Flags]
public enum Priority
{
Frequency1 = 1,
Frequency2 = 2,
Frequency3 = 4,
Frequency4 = 8
}
public interface IKanji
{
string Text { get; }
IEnumerable<KanjiInformation> Informations { get; }
Priority Priorities { get; }
}
In above consider each Priority as a bit in an int, you can add priority by using bitwise or (|) :
Priorities = Priority.Frequency1 | Priority.Frequency2 // means have both priorities
To check if it has specific priority use bitwise and (&):
if((Priorities & Priority.Frequency1) == Priority.Frequency1
{
// it contains Priority.Frequency1
}
Then the answer you were looking for will be like:
Priority p = Priority.Frequency1 | Priority.Frequency2 | Priority.Frequency3
var result = entries.Where(e => e.Kanjis.Any(k => k.Priorities & p == p)))
.ToList();
This could be one solution:
var filteredEntries = entries.Where( // Only entries
e => e.Kanjis.Any( // which have one or more kanjis with..
a => a.Priorities.Any( // which have one or more priorities
p => p.Value == "Frequency1" // which have a value of "Frequency1"
)));
I changed your interfaces to classes to make it run with some example-data:
public class IJapaneseDictionaryEntry
{
public int Sequence { get; set; }
public IEnumerable<IKanji> Kanjis { get; set; }
}
public class IKanji
{
public string Text { get; set; }
public IEnumerable<Priority> Priorities { get; set; }
}
public class Priority
{
public string Value { get; set; }
}
public static void Main(string[] args)
{
// Initialize 3 objects. One has Priority we're searching
List<IJapaneseDictionaryEntry> entries = new List<IJapaneseDictionaryEntry>()
{
new IJapaneseDictionaryEntry(){ Sequence = 1, Kanjis = new List<IKanji>() { new IKanji() { Priorities = new List<Priority>() { new Priority() { Value = "Frequency1" } } } } },
new IJapaneseDictionaryEntry(){ Sequence = 2, Kanjis = new List<IKanji>() { new IKanji() { Priorities = new List<Priority>() { new Priority() { Value = "Frequency2" } } } } },
new IJapaneseDictionaryEntry(){ Sequence = 3, Kanjis = new List<IKanji>() { new IKanji() { Priorities = new List<Priority>() { new Priority() { } } } } },
};
// Here's the magic:
var filteredEntries = entries.Where( // Only entries
e => e.Kanjis.Any( // which have one or more kanjis with..
a => a.Priorities.Any( // which have one or more priorities
p => p.Value == "Frequency1" // which have a value of "Frequency1"
)));
// Let's check the output
foreach (var e in filteredEntries)
{
Console.WriteLine(e.Sequence);
}
}

Is there a way to replace an object which is referenced in multiple lists with a new instance easily?

I would like to replace an object which is referenced in multiple lists with a new instance of matching interface class.
Here is an example to better understand the problem.
There is an interface called IPosition
There are two classes that implement that interface: RealPosition and AccessiblePosition
In my algorithm I am receiving an array of IPosition list, like this: List<IPosition>[], basically multiple lists
It is very common that the lists reference the same instance of an object. Here is a visualisation:
Now I would like to create a new instance of the AccessiblePosition class and update all references in all lists.
Is there a way to do that easily?
Many thanks in advance!
You can create a container for your data.
public interface IContainer<T>
{
T Data { get; set; }
}
And a List<IContainer<IPosition>>.
Now you can change Data of a container instead of changing item references.
You could just iterate through the lists and compare the items.
public interface IPosition
{
int ID { get; set; }
}
public class RealPosition : IPosition
{
public int ID { get; set; }
}
public class AccessiblePosition : IPosition
{
public int ID { get; set; }
}
void Main()
{
var toReplace = new RealPosition { ID = 1 };
var list1 = new List<IPosition>
{
toReplace,
new RealPosition { ID = 2 },
new RealPosition { ID = 3 },
};
var list2 = new List<IPosition>
{
toReplace,
new RealPosition { ID = 4 },
new RealPosition { ID = 5 },
};
var listOfLists = new List<List<IPosition>>{ list1, list2 };
var replacement = new AccessiblePosition{ ID = 42 };
foreach(var list in listOfLists)
{
//must use for here
for(int i = 0; i < list.Count; ++i)
{
if(list[i] == toReplace)
{
list[i] = replacement;
}
}
}
}

Updating Custom Class in List<T>

I am trying to update a List which is a List of Interfaces to concrete classes.
I add to the List each Market type i am interested in, for this Example these Markets are A and B
I loop over all the markets, (sample provided with 3 markets A B & C, we are only interested in A and B) And determine which is of interest to us.
Once found we pass this to an extraction method too do its work and create an instance of the Correct Market_ class type.
This all works fine, but when i try to update the list with the Updates it does not get reflected in the List.
Code below, any Suggestions?
Thanks
public class Test
{
public Test()
{
TheMarkets MarketsToUpdate = new TheMarkets();
List<SpecificCompanyMarket> lstMarks = new List<SpecificCompanyMarket>();
lstMarks.Add(new SpecificCompanyMarket(1234, "A", "Some HTML DATA HERE"));
lstMarks.Add(new SpecificCompanyMarket(5874, "B", "Some HTML DATA HERE"));
lstMarks.Add(new SpecificCompanyMarket(2224, "C", "Some HTML DATA HERE"));
foreach (var item in lstMarks)
{
if (MarketsToUpdate.IsMarketWeAreInterestedIn(item.MarketName))
{
ITheMarkets MarkToUpdate = ExtractMarketData(item);
var obj = MarketsToUpdate.MarketsWeAreInterestedIn.FirstOrDefault(x => x.MarketName() == "A");
if (obj != null)
{
obj = MarkToUpdate;
}
}
}
//Look At MarketsToUpdate Now and the item has not changed, still original values
//I was expecting to see the new values for the fields in A, not the default 0's
}
public ITheMarkets ExtractMarketData(SpecificCompanyMarket item)
{
ITheMarkets market = null;
if (item.MarketName.ToUpper() == "A")
{
Market_A marketType = new Market_A();
marketType.SomeValue1 = 123;
marketType.SomeValue2 = 158253;
market = marketType;
}
//Other Market extractions here
return market;
}
}
public class SpecificCompanyMarket
{
public int MarketId { get; set; }
public string MarketName { get; set; }
public string MarketDataHTML { get; set; }
public SpecificCompanyMarket(int MID, string MName, string MData)
{
MarketId = MID;
MarketName = MName;
MarketDataHTML = MData;
}
}
public class TheMarkets
{
public List<ITheMarkets> MarketsWeAreInterestedIn = new List<ITheMarkets>();
public TheMarkets()
{
Market_A A = new Market_A();
Market_B B = new Market_B();
MarketsWeAreInterestedIn.Add(A);
MarketsWeAreInterestedIn.Add(B);
}
public bool IsMarketWeAreInterestedIn(string strMarketName)
{
bool blnRetVal = false;
foreach (var item in MarketsWeAreInterestedIn)
{
if (item.MarketName().ToUpper().Trim().Equals(strMarketName.ToUpper().Trim()))
{
blnRetVal = true;
break;
}
}
return blnRetVal;
}
}
public interface ITheMarkets
{
string MarketName();
}
public class Market_A : ITheMarkets
{
public string LabelType { get; private set; }
public double SomeValue1 { get; set; }
public double SomeValue2 { get; set; }
public double SomeValue3 { get; set; }
public Market_A()
{
LabelType = "A";
}
public string MarketName()
{
return LabelType;
}
}
public class Market_B : ITheMarkets
{
public string LabelType { get; private set; }
public List<string> SomeList { get; set; }
public double SomeValue { get; set; }
public Market_B()
{
LabelType = "B";
}
public string MarketName()
{
return LabelType;
}
}
This is a short example to get you going. Loop through your list, find the object you want to update, create a new object of that type and then find the original objects index in the list and overwrite it in place. You are essentially just replacing the object in the list with a new one not mutating the existing one.
foreach (var item in lstMarks)
{
//your code to get an object with data to update
var yourObjectToUpdate = item.GetTheOneYouWant();
//make updates
yourObjectToUpdate.SomeProperty = "New Value";
int index = lstMarks.IndexOf(item);
lstMarks[index] = yourObjectToUpdate;
}
You are extracting an obj from marketWeAreInterestedIn list using LINQ's firstOrDefault extension. This is a new object and not a reference to the obj in that list. Therefore, no updates will be reflected in the object inside that list. Try using 'indexof'
You are not storing "list of interfaces" in your list. List<T> stores an array of pointers to objects that support T interface. Once you enumerate (with Linq in your case) your list, you copy a pointer from list, which is not associated with list itself in any way. It is just a pointer to your instance.
To do what you want, you will have to build new list while enumerating the original one, adding objects to it, according to your needs, so the second list will be based on the first one but with changes applied that you need.
You can also replace specific instance at specific index instead of building new list in your code, but to do this you will need to enumerate your list with for loop and know an index for each item:
list[index] = newvalue;
But there is a third solution to update list item directly by Proxying them. This is an example
class ItemProxy : T { public T Value { get; set; } }
var list = new List<ItemProxy<MyClass>>();
list.Insert(new ItemProxy { Value = new MyClass() });
list.Insert(new ItemProxy { Value = new MyClass() });
list.Insert(new ItemProxy { Value = new MyClass() });
foreach(var item in list)
if(item // ...)
item.Value = new MyClass(); // done, pointer in the list is updated.
Third is the best case for perfomance, but it will be better to use this proxying class for something more than just proxying.

generate all possible combinations for a dynamic list of attributes with their values

I struggle with generating all possible combinations for a List of Attributes with their possible values. What I would like to implement is a Method like this:
public List<Variant> generateAllPossibleVariants(List<Attribute> attributes)
The Attribute Class looks the following:
public class Attribute {
public String Name { get; set; }
public ICollection<String> PossibleValues { get; protected set; }
}
So imagine you have a list of 2 Attributes (while the count is dynamic) with their possible values:
attributeColor with possible Values of ( "red", "blue" )
attributeSize with possible values of ("XL", "L" )
Now my method should return a List of Variant while the Variant Class looks the following:
public class Variant
{
public IDictionary<Attribute, string> AttributeValues { get; private set; }
}
Now my method should return a List of all combinations like the following:
List<Variant> :
Variant.AttributeValues { attributeColor => "red", attributeSize => "XL" }
Variant.AttributeValues { attributeColor => "red", attributeSize => "L" }
Variant.AttributeValues { attributeColor => "blue", attributeSize => "XL" }
Variant.AttributeValues { attributeColor => "blue", attributeSize => "L" }
This is not an optimized code, but you can get the idea and clean it up yourself:
public void Main()
{
var attr1 = new MyAttribute { Name = "Colors", PossibleValues = new List<string> { "red", "blue" } };
var attr2 = new MyAttribute { Name = "Sizes", PossibleValues = new List<string> { "XL", "L" } };
var attr3 = new MyAttribute { Name = "Shapes", PossibleValues = new List<string> { "qube", "circle" } };
var attrList = new List<MyAttribute> { attr1, attr2, attr3 };
var result = attrList.Skip(1).Aggregate<MyAttribute, List<Variant>>(
new List<Variant>(attrList[0].PossibleValues.Select(s => new Variant { AttributeValues = new Dictionary<MyAttribute, string> { {attrList[0], s} } })),
(acc, atr) =>
{
var aggregateResult = new List<Variant>();
foreach (var createdVariant in acc)
{
foreach (var possibleValue in atr.PossibleValues)
{
var newVariant = new Variant { AttributeValues = new Dictionary<MyAttribute, string>(createdVariant.AttributeValues) };
newVariant.AttributeValues[atr] = possibleValue;
aggregateResult.Add(newVariant);
}
}
return aggregateResult;
});
}
public class MyAttribute
{
public string Name { get; set; }
public ICollection<string> PossibleValues { get; set; }
}
public class Variant
{
public IDictionary<MyAttribute, string> AttributeValues { get; set; }
}
You are looking for cartesian product (with dynamic dimension).
One simple way to achieve it is using recursion on the dimension, and each time invoke cartesian product on the result of the recursion, and one of the dimensions.
Pseudo code:
genAllPossibilities(list attributes) //each element in attributes is a list
if length(attributes) == 1:
return attributes[0] //the only element, which is a list of one attribute
else:
curr = head(attributes) // first element in the list
reminder = tails(attributes) // a list of all elements except the first
return cartesianProduct(genAllPossibilities(reminder), curr)
cartesianProduct(list1, list2):
l = new list
for each x1 in list1:
for each x2 in list2:
l.append(new MyObject(x1,x2))
return l

Splitting a complex object to two separated key and value collections

I'm trying to implement the C# aspect of a LightWeight JSON Spec JsonR, but cannot get my head around any kind of recursion :-/ If anyone could help out here it would be more than greatly appreciated.
// Mockup class
public class User {
public string Name { get; set; }
public int Age { get; set; }
public List<string> Photos { get; set; }
public List<Friend> Friends { get; set; }
}
// Mockup class
public class Friend {
public string FirstName { get; set; }
public string LastName { get; set; }
}
// Initialize objects
var userList = new List<User>();
userList.Add(new User() {
Name = "Robert",
Age = 32,
Photos = new List<string> { "1.jpg", "2.jpg" },
Friends = new List<Friend>() {
new Friend() { FirstName = "Bob", LastName = "Hope"},
new Friend() { FirstName = "Mr" , LastName = "T"}
}
});
userList.Add(new User() {
Name = "Jane",
Age = 21,
Photos = new List<string> { "4.jpg", "5.jpg" },
Friends = new List<Friend>() {
new Friend() { FirstName = "Foo" , LastName = "Bar"},
new Friend() { FirstName = "Lady" , LastName = "Gaga"}
}
});
The idea behind it all is to now take the above object and split it into 2 separate collections, one containing the keys, and the other containing the values. Like this we can eventually only send the values over the wire thus saving lots of bandwidth, and then recombine it on the client (a js implementation for recombining exists already)
If all went well we should be able to get this out of the above object
var keys = new object[] {
"Name", "Age", "Photos",
new { Friends = new [] {"FirstName", "LastName"}}};
var values = new [] {
new object[] {"Robert", 32, new [] {"1.jpg", "2.jpg"},
new [] { new [] {"Bob", "Hope"},
new [] {"Mr", "T"}}},
new object[] {"Jane", 21, new [] {"4.jpg", "5.jpg"},
new [] { new [] {"Foo", "Bar"},
new [] {"Lady", "Gaga"}}}};
As a verification we can test the conformity of the result with
Newtonsoft.Json.JsonConvert.SerializeObject(keys).Dump("keys");
// Generates:
// ["Name","Age","Photos",{"Friends":["FirstName","LastName"]}]
Newtonsoft.Json.JsonConvert.SerializeObject(values).Dump("values");
// Generates:
// [["Robert",32,["1.jpg","2.jpg"],[["Bob","Hope"],["Mr","T"]]],["Jane",21,["4.jpg","5.jpg"],[["Foo","Bar"],["Lady","Gaga"]]]]
A shortcut i explored was to take advantage of Newton's JArray/JObject facilities like this
var JResult = Newtonsoft.Json.JsonConvert.DeserializeObject(
Newtonsoft.Json.JsonConvert.SerializeObject(userList));
Like this we end up with a sort of array object that we can already start iterating on
Anyone think they can crack this in a memory/speed efficient way ?
I have a solution that works with your example data. It is not a universal solution and may fail with other examples, but it shows how to use recursions. I did not include any error handling. A real-world solution would have to.
I use this helper method which gets the item type of the generic lists:
private static Type GetListItemType(Type listType)
{
Type itemType = null;
foreach (Type interfaceType in listType.GetInterfaces()) {
if (interfaceType.IsGenericType &&
interfaceType.GetGenericTypeDefinition() == typeof(IList<>)) {
itemType = interfaceType.GetGenericArguments()[0];
break;
}
}
return itemType;
}
Now, the recursion:
public void SplitKeyValues(IList source, List<object> keys, List<object> values)
{
Type itemType = GetListItemType(source.GetType());
PropertyInfo[] properties = itemType.GetProperties();
for (int i = 0; i < source.Count; i++) {
object item = source[i];
var itemValues = new List<object>();
values.Add(itemValues);
foreach (PropertyInfo prop in properties) {
if (typeof(IList).IsAssignableFrom(prop.PropertyType) &&
prop.PropertyType.IsGenericType) {
// We have a List<T> or array
Type genericArgType = GetListItemType(prop.PropertyType);
if (genericArgType.IsValueType || genericArgType == typeof(string)) {
// We have a list or array of a simple type
if (i == 0)
keys.Add(prop.Name);
List<object> subValues = new List<object>();
itemValues.Add(subValues);
subValues.AddRange(
Enumerable.Cast<object>(
(IEnumerable)prop.GetValue(item, null)));
} else {
// We have a list or array of a complex type
List<object> subKeys = new List<object>();
if (i == 0)
keys.Add(subKeys);
List<object> subValues = new List<object>();
itemValues.Add(subValues);
SplitKeyValues(
(IList)prop.GetValue(item, null), subKeys, subValues);
}
} else if (prop.PropertyType.IsValueType ||
prop.PropertyType == typeof(string)) {
// We have a simple type
if (i == 0)
keys.Add(prop.Name);
itemValues.Add(prop.GetValue(item, null));
} else {
// We have a complex type.
// Does not occur in your example
}
}
}
}
I call it like this:
List<User> userList = InitializeObjects();
List<object> keys = new List<object>();
List<object> values = new List<object>();
SplitKeyValues(userList, keys, values);
InitializeObjects initializes the user list as you did above.
UPDATE
The problem is that you are using an anonymous type new { Friends = ... }. You would have to create an anonymous type dynamically by using reflection. And that's pretty nasty. The article "Extend Anonymous Types using Reflection.Emit" seems to do it. (I didn't test it).
Maybe an easier approach would do the job. I suggest creating a helper class for the description of class types.
public class Class
{
public string Name { get; set; }
public List<object> Structure { get; set; }
}
Now let's replace an else case in the code above:
...
} else {
// We have a list or array of a complex type
List<object> subKeys = new List<object>();
var classDescr = new Class { Name = genericArgType.Name, Structure = subKeys };
if (i == 0)
keys.Add(classDescr);
List<object> subValues = new List<object>();
itemValues.Add(subValues);
SplitKeyValues(
(IList)prop.GetValue(item, null), subKeys, subValues);
}
...
The result is:
You may want to try an external tool, like AutoMapper, which is a convention based mapping library.
I suggest to try the flattening feature with your own conventions.
I'm sorry I cannot write out an example because of lack of time, but I think the ideas behind this open source library might help a lot.

Categories

Resources