Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use C# Linq Lambda to combine fields from two objects into one, preferably without anonymous objects

Tags:

c#

lambda

linq

I have a class setup like this:

 public class Summary
{
    public Geometry geometry { get; set; }
    public SummaryAttributes attributes { get; set; }
}
public class SummaryAttributes
{
    public int SERIAL_NO { get; set; }
    public string District { get; set; }
 }
public class Geometry
{
    public List<List<List<double>>> paths { get; set; }
}

and i take a json string of records for that object and cram them in there like this:

List<Summary> oFeatures = reportObject.layers[0].features.ToObject<List<Summary>>();

my end goal is to create a csv file so i need one flat List of records to send to the csv writer i have. I can do this:

 List<SummaryAttributes> oAtts = oFeatures.Select(x => x.attributes).ToList();

and i get a nice List of the attributes and send that off to csv. Easy peasy.

What i want though is to also pluck a field off of the Geometry object as well and include that in my final List to go to csv. So the final List going to the csv writer would contain objects with all of the fields from SummaryAttributes plus the first and last double values from the paths field on the Geometry object (paths[0][0][first] and paths[0][0][last])

It's hard to explain. I want to graft two extra attributes onto the original SummaryAttributes object. I would be ok with creating a new SummaryAttributesXY class with the two extra fields if that's what it takes. But i'm trying to avoid creating a new anonymous object and having to delimit every field in the SummaryAttributes class as there are many more than i have listed in this sample.

Any suggestions?

like image 826
VBAHole Avatar asked Mar 22 '17 15:03

VBAHole


People also ask

What does %d do?

%d takes integer value as signed decimal integer i.e. it takes negative values along with positive values but values should be in decimal otherwise it will print garbage value.

Where is C most used?

C is commonly used on computer architectures that range from the largest supercomputers to the smallest microcontrollers and embedded systems. A successor to the programming language B, C was originally developed at Bell Labs by Ritchie between 1972 and 1973 to construct utilities running on Unix.


2 Answers

You can select new anonymous object with required fields, but you should be completely sure that paths has at least one item in each level of lists:

var query = oFeatures.Select(s => new {
  s.attributes.SERIAL_NO,
  s.attributes.District,
  First = s.geometry.paths[0][0].First(), // or [0][0][0]
  Last = s.geometry.paths[0][0].Last()   
}).ToList()
like image 165
Sergey Berezovskiy Avatar answered Nov 14 '22 23:11

Sergey Berezovskiy


Got it figured out. I include the X and Y fields in the original class definition. When the json gets deserialized they will be null. Then i loop back and fill them in.

 List<Summary> oFeatures = reportObject.layers[0].features.ToObject<List<Summary>>();
                List<Summary> summary = oFeatures.Select(s =>
                {
                    var t = new Summary
                    {
                        attributes = s.attributes
                    };
                    t.attributes.XY1 = string.Format("{0} , {1}", s.geometry.paths[0][0].First(), s.geometry.paths[0][1].First());
                    t.attributes.XY2 = string.Format("{0} , {1}", s.geometry.paths[0][0].Last(), s.geometry.paths[0][1].First());
                    return t;
                }).ToList();
                List<SummaryAttributes> oAtts = summary.Select(x => x.attributes).ToList();
like image 24
VBAHole Avatar answered Nov 14 '22 21:11

VBAHole