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: 
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
Post a Comment