HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Mapping array to class properties

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arraymappingclassproperties

Problem

I am wondering what is the best way to map array values to properties in a class. Consider the following sample array describing information for an airport:

[0] "6523"  string
        [1] "00A"   string
        [2] "heliport"  string
        [3] "Total Rf Heliport" string
        [4] "40.07080078125"    string
        [5] "-74.9336013793945" string
        [6] "11"    string
        [7] "NA"    string
        [8] "US"    string
        [9] "US-PA" string
        [10]    "Bensalem"  string
        [11]    "no"    string
        [12]    "00A"   string
        [13]    ""  string
        [14]    "00A"   string
        [15]    ""  string
        [16]    ""  string
        [17]    ""  string


I have the following class:

```
public class Airport
{
public Airport(string[] data)
{
Action[] PropertyMappings =
{
x=>this.Id=x,
x=>this.Ident=x,
x=>this.Type=x,
x=>this.Name=x,
x=>this.Latitude=x,
x=>this.Longtitude=x,
x=>this.Elevation=x,
x=>this.Continent=x,
x=>this.CountryIso=x,
x=>this.RegionIso=x,
x=>this.Municipality=x,
x=>this.ScheduledService=x,
x=>this.GPSCode=x,
x=>this.DataCode=x,
x=>this.LocalCode=x,
x=>this.HomeLink=x,
x=>this.WikipediaLink=x,
x=>this.Keywords=x
};
for(int i=0;i<data.Count();i++)
{
PropertyMappingsi;
}
}
public string Id { get; set; }
public string Ident { get; set; }
public string Type { get; set; }
public string Name { get; set; }
public string Latitude { get; set; }
public string Longtitude { get; set; }
public string Elevation { get; set; }
public string Continent { g

Solution

As you said that you will always have the right number of elements in the array, I would suggest the following:

public class Airport
{
    public string Id { get; set; }
    public string Ident { get; set; }
    public string Type { get; set; }
    public string Name { get; set; }
    public string Latitude { get; set; }
    public string Longtitude { get; set; }
    public string Elevation { get; set; }
    public string Continent { get; set; }
    public string CountryIso { get; set; }
    public string RegionIso { get; set; }
    public string Municipality { get; set; }
    public string ScheduledService { get; set; }
    public string GPSCode { get; set; }
    public string DataCode { get; set; }
    public string LocalCode { get; set; }
    public string HomeLink { get; set; }
    public string WikipediaLink { get; set; }
    public string Keywords { get; set; }

    public static Airport CreateFromData(string[] data)
    {
        if (data.Length != 18) {
            throw new ArgumentException("...");
        }
        return new Airport
                   {
                       Id = data[0],
                       Ident = data[1],
                       Type = data[2],
                       Name = data[3],
                       Latitude = data[4],
                       Longtitude = data[5],
                       Elevation = data[6],
                       Continent = data[7],
                       CountryIso = data[8],
                       RegionIso = data[9],
                       Municipality = data[10],
                       ScheduledService = data[11],
                       GPSCode = data[12],
                       DataCode = data[13],
                       LocalCode = data[14],
                       HomeLink = data[15],
                       WikipediaLink = data[16],
                       Keywords = data[17]
                   };
    }        
}


Depending on usage I would suggest that you alter the accessibility of the setters on the properties and consider making the default constructor protected (if you only want to create via a data array).

Why am I making this suggestion?

  • Keeps it simple



  • It's about 30 times faster than your method



  • You can view the code as a schema for the data array. I.e. Type is the third element



Edit

As RufusL notes in the comments, it would be a good idea to add a null check for the data array:

public static Airport CreateFromData(string[] data)
{
    if (data == null) {
        throw new ArgumentNullException("data");
    }
    if (data.Length != 18)
    {
        ...


Further to my comment about my proposed solution being faster - it's not because your code is slow in any way. If you want a dictionary of mappings of property -> index in data array your code will be slower but that probably wont matter.

You could just move your array of property mappings to a field. Just change the signature to Action[] you'd then populate it like:

Action[] PropertyMappings = 
{
     (a, s) => a.Id = s,
     // ...
}

public static Airport CreateFromData(string[] data)
{
    // Guards omitted.
    var result = new Airport();
    for (var i = 0; i < data.Length; i++) 
    {
        PropertyMappings(result, data[i]);
    }
    return result;
}


(all of the code in the edit has just been typed directly in the browser, if it doesn't compile, hopefully it should be close enough to correct.)

Code Snippets

public class Airport
{
    public string Id { get; set; }
    public string Ident { get; set; }
    public string Type { get; set; }
    public string Name { get; set; }
    public string Latitude { get; set; }
    public string Longtitude { get; set; }
    public string Elevation { get; set; }
    public string Continent { get; set; }
    public string CountryIso { get; set; }
    public string RegionIso { get; set; }
    public string Municipality { get; set; }
    public string ScheduledService { get; set; }
    public string GPSCode { get; set; }
    public string DataCode { get; set; }
    public string LocalCode { get; set; }
    public string HomeLink { get; set; }
    public string WikipediaLink { get; set; }
    public string Keywords { get; set; }

    public static Airport CreateFromData(string[] data)
    {
        if (data.Length != 18) {
            throw new ArgumentException("...");
        }
        return new Airport
                   {
                       Id = data[0],
                       Ident = data[1],
                       Type = data[2],
                       Name = data[3],
                       Latitude = data[4],
                       Longtitude = data[5],
                       Elevation = data[6],
                       Continent = data[7],
                       CountryIso = data[8],
                       RegionIso = data[9],
                       Municipality = data[10],
                       ScheduledService = data[11],
                       GPSCode = data[12],
                       DataCode = data[13],
                       LocalCode = data[14],
                       HomeLink = data[15],
                       WikipediaLink = data[16],
                       Keywords = data[17]
                   };
    }        
}
public static Airport CreateFromData(string[] data)
{
    if (data == null) {
        throw new ArgumentNullException("data");
    }
    if (data.Length != 18)
    {
        ...
Action<Airport, string>[] PropertyMappings = 
{
     (a, s) => a.Id = s,
     // ...
}

public static Airport CreateFromData(string[] data)
{
    // Guards omitted.
    var result = new Airport();
    for (var i = 0; i < data.Length; i++) 
    {
        PropertyMappings(result, data[i]);
    }
    return result;
}

Context

StackExchange Code Review Q#76922, answer score: 8

Revisions (0)

No revisions yet.