linq - Solving C# Collection Mismatch -


i have 2 collections - 1 contains product title - second contains shipping information. way retrieve information guarantees each position in each collection go together, i.e. position [0] in collection 1 goes position[0] in collection 2. however, whenever same customer orders 2 or more different items no longer true - creates mismatch in collection.

in example below same customer, dave lain, orders 2 different items, filling 2 different potions in 'b' collection, fill 1 position in 'a' collection. when go iterate both collections - won't match correctly , wrong person credited wrong order.

xml file of product titles collection 'b':

<listorderitems>     <orderitem>         <title>itemfromcustomer1</title>     </orderitem>     <orderitem>         <title>itemfromcustomer1</title>     </orderitem>     <orderitem>         <title>itemfromcustomer2</title>     </orderitem>     <orderitem>         <title>itemfromcustomer3</title>     </orderitem> </listorderitems> 

shipping information collection 'a':

<listordersresult>     <orders>         <order>             <name>dave lain</name>             <addressline1>630232 jekass rd</addressline1>             <city>paris</city>             <stateorregion>tx</stateorregion>             <postalcode>3281\8-5454</postalcode>             <countrycode>us</countrycode>             <phone>407745186</phone         </order>         <order>             <name>joe schmo</name>             <addressline1>635232 cherry rd</addressline1>             <city>paris</city>             <stateorregion>tx</stateorregion>             <postalcode>876458</postalcode>             <countrycode>us</countrycode>             <phone>5425546574</phone                           </order>         <order>             <name>ray charles</name>             <addressline1>6384 red dr</addressline1>             <city>miami</city>             <stateorregion>fl</stateorregion>             <postalcode>78457</postalcode>             <countrycode>us</countrycode>             <phone>5478975487</phone                           </order>     </orders> </listordersresult> 

my foreach loop uses zip method iterate through both collections in parallel, when gets double order, becomes off.

foreach (var address in addresses.zip(products, (a, b) => new {a, b})) {         if (string.equals(address.b.title, denatalcohol, stringcomparison.currentcultureignorecase))     {         //execute code if product title match     }      if (string.equals(address.b.title, sodiumchlorate, stringcomparison.currentcultureignorecase))     {         //execute code if product title match     }     if (string.equals(address.b.title, seminitric, stringcomparison.currentcultureignorecase))     {         //execute code if product title match     }     if (string.equals(address.b.title, lesernitric, stringcomparison.currentcultureignorecase))     {         //execute code if product title match     }     if (stringarray.any(address.b.title.contains))     {         //execute code if product title match                             }     if (address.b.title.equals(isopropyl))     {         //execute code if product title match                }     if (address.b.title.equals(haznitric))     {         //execute code if product title matchg     }          if (address.a.addressline2 != null)     {         //execute code info in collection shipping address info     }     else     {         //execute code info in collection shipping address info     } } 

since example not provide info of sort of keys enforce relationship between order elements , orderitem elements assume title semantic key.

the enumerable.zip method

combines elements until reaches end of 1 of sequences.

as happens example,

[...] if 1 sequence has 3 elements , other 1 has four, result sequence has 3 elements.

so, happens zip method on second step associates orderitem itemfromcustomer1 second order element sequence joe schmo.

what need group orderitems , flatten collection this:

addresses.descendants("order")     .zip(orders.descendants("orderitem")                 .groupby(e=>e.element("title").value),              (a, o) => new{a,o})     .selectmany(tuple => tuple.o.select(x => new{tuple.a, o = x})); 

this result in linqpad: query results.

however, keep in mind this not proper way it! need define relationship between order elements , orderitem elements enforced sort of foreign key can perform proper join on collections without ordering concerns; this:

addresses.descendants("order")     .join(orders.descendants("orderitem"),         order => order.element("id").value,         orderitem => orderitem.element("orderid").value,         (order, orderitem) => new{order, orderitem}); 

Comments