Finding the nearest agents to a customer using IComparableMulti-tiered sorting using custom IComparerIComparable comparisionWebAPI - Return models vs entity and partial class with meta dataExceptions or something else?IComparable implementation for a class representing a versionSorting algorithmFinding travel distance between airportsRectangle Classpancake sorting using pythonSorting table using multiple columns

...And they were stumped for a long time

What is the use case for non-breathable waterproof pants?

Can we assume that a hash function with high collision resistance also means highly uniform distribution?

Why did Jon Snow do this immoral act if he is so honorable?

Why sampling a periodic signal doesn't yield a periodic discrete signal?

Variable declaraton with extra in C

Of strange atmospheres - the survivable but unbreathable

Must a warlock replace spells with new spells of exactly their Pact Magic spell slot level?

Gravitational Force Between Numbers

Which European Languages are not Indo-European?

How would a developer who mostly fixed bugs for years at a company call out their contributions in their CV?

Python program for fibonacci sequence using a recursive function

Is "vegetable base" a common term in English?

How to keep consistency across the application architecture as a team grows?

Using too much dialogue?

Is there an idiom that means that you are in a very strong negotiation position in a negotiation?

Navigating a quick return to previous employer

Is superuser the same as root?

Why does Bran want to find Drogon?

Why would a rational buyer offer to buy with no conditions precedent?

Are cells guaranteed to get at least one mitochondrion when they divide?

Can a UK national work as a paid shop assistant in the USA?

Where is Jon going?

Why isn't 'chemically-strengthened glass' made with potassium carbonate? To begin with?



Finding the nearest agents to a customer using IComparable


Multi-tiered sorting using custom IComparerIComparable comparisionWebAPI - Return models vs entity and partial class with meta dataExceptions or something else?IComparable implementation for a class representing a versionSorting algorithmFinding travel distance between airportsRectangle Classpancake sorting using pythonSorting table using multiple columns






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








5












$begingroup$


I got a C# class:



public class Agent 

public string AgentId set; get;
public double Longitude set; get;
public double Latitude set; get;



There are several agents in several different locations. During the program's lifetime, they can receive a call to another (latitude, longitude) point which is unknown during runtime. I got an API to calculate the distance in meters between their location and the given point. What I need eventually is to find the 5 closest agents to the given point.



What I did in order to achieve this is adding another class:



public class AgentDistance : Agent, IComparable<AgentDistance>


public AgentDistance(Agent agent)

if(agent == null)

throw new Exception("Can't initalize agent with distance since agent is null");

this.AgentId = agent.AgentId;
this.Latitude = agent.Latitude;
this.Longitude = agent.Longitude;


public double Distance set; get;

public int CompareTo(AgentDistance other)

if(other == null)

return 1;

return Distance.CompareTo(other.Distance);




And the usage:



var agents = db.GetAgents();
if(agents == null || agents.Count == 0)

Console.WriteLine("No Results");

List<AgentDistance> agentsWithDistance = new List<AgentDistance>();
foreach(Agent agent in agents)

double res = ws.GetDistanceMeters(agent.Latitude, agent.Longitude, customerLatitude, customerLongitude);
agentsWithDistance.Add(new AgentDistance(agent) Distance = res );

agentsWithDistance.Sort();
for(int i = 0; i < 5; i++)

Console.WriteLine(string.Format("agent_id: 0 distance: 1 m", agentsWithDistance[i].AgentId, agentsWithDistance[i].Distance));



It works, but is there a more elegant way to do it? I'm not sure if adding another class might be a bit redundant since all it does is just adding a property for sorting, but adding the distance property to the Agent class, doesn't make so much sense.










share|improve this question









New contributor



Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$


















    5












    $begingroup$


    I got a C# class:



    public class Agent 

    public string AgentId set; get;
    public double Longitude set; get;
    public double Latitude set; get;



    There are several agents in several different locations. During the program's lifetime, they can receive a call to another (latitude, longitude) point which is unknown during runtime. I got an API to calculate the distance in meters between their location and the given point. What I need eventually is to find the 5 closest agents to the given point.



    What I did in order to achieve this is adding another class:



    public class AgentDistance : Agent, IComparable<AgentDistance>


    public AgentDistance(Agent agent)

    if(agent == null)

    throw new Exception("Can't initalize agent with distance since agent is null");

    this.AgentId = agent.AgentId;
    this.Latitude = agent.Latitude;
    this.Longitude = agent.Longitude;


    public double Distance set; get;

    public int CompareTo(AgentDistance other)

    if(other == null)

    return 1;

    return Distance.CompareTo(other.Distance);




    And the usage:



    var agents = db.GetAgents();
    if(agents == null || agents.Count == 0)

    Console.WriteLine("No Results");

    List<AgentDistance> agentsWithDistance = new List<AgentDistance>();
    foreach(Agent agent in agents)

    double res = ws.GetDistanceMeters(agent.Latitude, agent.Longitude, customerLatitude, customerLongitude);
    agentsWithDistance.Add(new AgentDistance(agent) Distance = res );

    agentsWithDistance.Sort();
    for(int i = 0; i < 5; i++)

    Console.WriteLine(string.Format("agent_id: 0 distance: 1 m", agentsWithDistance[i].AgentId, agentsWithDistance[i].Distance));



    It works, but is there a more elegant way to do it? I'm not sure if adding another class might be a bit redundant since all it does is just adding a property for sorting, but adding the distance property to the Agent class, doesn't make so much sense.










    share|improve this question









    New contributor



    Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    $endgroup$














      5












      5








      5





      $begingroup$


      I got a C# class:



      public class Agent 

      public string AgentId set; get;
      public double Longitude set; get;
      public double Latitude set; get;



      There are several agents in several different locations. During the program's lifetime, they can receive a call to another (latitude, longitude) point which is unknown during runtime. I got an API to calculate the distance in meters between their location and the given point. What I need eventually is to find the 5 closest agents to the given point.



      What I did in order to achieve this is adding another class:



      public class AgentDistance : Agent, IComparable<AgentDistance>


      public AgentDistance(Agent agent)

      if(agent == null)

      throw new Exception("Can't initalize agent with distance since agent is null");

      this.AgentId = agent.AgentId;
      this.Latitude = agent.Latitude;
      this.Longitude = agent.Longitude;


      public double Distance set; get;

      public int CompareTo(AgentDistance other)

      if(other == null)

      return 1;

      return Distance.CompareTo(other.Distance);




      And the usage:



      var agents = db.GetAgents();
      if(agents == null || agents.Count == 0)

      Console.WriteLine("No Results");

      List<AgentDistance> agentsWithDistance = new List<AgentDistance>();
      foreach(Agent agent in agents)

      double res = ws.GetDistanceMeters(agent.Latitude, agent.Longitude, customerLatitude, customerLongitude);
      agentsWithDistance.Add(new AgentDistance(agent) Distance = res );

      agentsWithDistance.Sort();
      for(int i = 0; i < 5; i++)

      Console.WriteLine(string.Format("agent_id: 0 distance: 1 m", agentsWithDistance[i].AgentId, agentsWithDistance[i].Distance));



      It works, but is there a more elegant way to do it? I'm not sure if adding another class might be a bit redundant since all it does is just adding a property for sorting, but adding the distance property to the Agent class, doesn't make so much sense.










      share|improve this question









      New contributor



      Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      $endgroup$




      I got a C# class:



      public class Agent 

      public string AgentId set; get;
      public double Longitude set; get;
      public double Latitude set; get;



      There are several agents in several different locations. During the program's lifetime, they can receive a call to another (latitude, longitude) point which is unknown during runtime. I got an API to calculate the distance in meters between their location and the given point. What I need eventually is to find the 5 closest agents to the given point.



      What I did in order to achieve this is adding another class:



      public class AgentDistance : Agent, IComparable<AgentDistance>


      public AgentDistance(Agent agent)

      if(agent == null)

      throw new Exception("Can't initalize agent with distance since agent is null");

      this.AgentId = agent.AgentId;
      this.Latitude = agent.Latitude;
      this.Longitude = agent.Longitude;


      public double Distance set; get;

      public int CompareTo(AgentDistance other)

      if(other == null)

      return 1;

      return Distance.CompareTo(other.Distance);




      And the usage:



      var agents = db.GetAgents();
      if(agents == null || agents.Count == 0)

      Console.WriteLine("No Results");

      List<AgentDistance> agentsWithDistance = new List<AgentDistance>();
      foreach(Agent agent in agents)

      double res = ws.GetDistanceMeters(agent.Latitude, agent.Longitude, customerLatitude, customerLongitude);
      agentsWithDistance.Add(new AgentDistance(agent) Distance = res );

      agentsWithDistance.Sort();
      for(int i = 0; i < 5; i++)

      Console.WriteLine(string.Format("agent_id: 0 distance: 1 m", agentsWithDistance[i].AgentId, agentsWithDistance[i].Distance));



      It works, but is there a more elegant way to do it? I'm not sure if adding another class might be a bit redundant since all it does is just adding a property for sorting, but adding the distance property to the Agent class, doesn't make so much sense.







      c# sorting geospatial






      share|improve this question









      New contributor



      Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share|improve this question









      New contributor



      Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share|improve this question




      share|improve this question








      edited 45 mins ago









      200_success

      132k20159426




      132k20159426






      New contributor



      Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      asked 13 hours ago









      Yonatan NirYonatan Nir

      1284




      1284




      New contributor



      Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




      New contributor




      Yonatan Nir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          3 Answers
          3






          active

          oldest

          votes


















          7












          $begingroup$


          var agents = db.GetAgents();
          if(agents == null || agents.Count == 0)

          Console.WriteLine("No Results");




          You should exit your application/code block when you detect an invalid state. Here even if "No Results" is printed, the app will still run into a NullReferenceException or IndexOutOfRangeException in the next few steps. Also, talking of IndexOutOfRangeException, there is no check against if there is at least 5 agents in your db.



          Instead of creating an IComparable, you can just use linq to sort directly. But, since in your case, you also need to print out the distance (the value used for sorting), we will need to create an anonymous class to hold it:



          var agents = db.GetAgents();
          if(agents == null || agents.Count == 0)

          Console.WriteLine("No Results");
          return;


          var nearestAgents = agents
          .Select(x => new

          x.AgentId,
          x.Latitude, x.Longitude,
          DistanceToCustomer = ws.GetDistanceMeters(x.Latitude, x.Longitude, customerLatitude, customerLongitude)
          )
          .OrderBy(x => x.DistanceToCustomer);
          foreach (var agent in nearestAgents.Take(5))

          Console.WriteLine($"agent_id: agent.AgentId distance: agent.DistanceToCustomer m");



          The .Take(5) ensures that only 5 agent will be printed out, or less.






          share|improve this answer











          $endgroup$












          • $begingroup$
            The anonymous class doesn't need the x.Latitude and x.Longitude fields.
            $endgroup$
            – 200_success
            43 mins ago


















          4












          $begingroup$

          I'd say you have the following options:




          1. Keep that new class if you think it's relevant in your business. Here, it should be important to know if the logic of calculate the distance should be on that web service (I assume that 'ws' variable means that) or within your model (i.e., the 'Agent' class).


          2. Use an anonymous class if you think you won't pass that info to another method.


          3. Use a dictionary if you think it's not relevant in your business but will pass that info to another method.

          Personally, I'd go for the first one since it's the most natural to me. By the way, I'd use LINQ's OrderBy instead of implementing the IComparable interface; again, for expressiveness.






          share|improve this answer









          $endgroup$




















            0












            $begingroup$

            I think, I would hold on to your decorator pattern because it is more reusable than the selection with anonymous objects.



             public class DistancedAgent : Agent

            public DistancedAgent(Agent source, double distance)

            AgentId = source.AgentId;
            Latitude = source.Latitude;
            Longitude = source.Longitude;
            Distance = distance;


            public double Distance get;

            public override string ToString()

            return $"Latitude, Longitude => Distance";




            You could extent Agent with some converter methods:



             public static class Extensions

            public static DistancedAgent WithDistance(this Agent agent, Func<Agent, double> getDistance)

            return new DistancedAgent(agent, getDistance(agent));


            public static DistancedAgent WithDistance(this Agent agent, IDistanceProvider distanceProvider)

            return new DistancedAgent(agent, distanceProvider.GetDistance(agent));


            public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, Func<Agent, double> getDistance)

            return agents?.Where(a => a != null).Select(a => a.WithDistance(getDistance)) ?? new DistancedAgent[0];


            public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, IDistanceProvider distanceProvider)

            return agents?.Where(a => a != null).Select(a => a.WithDistance(distanceProvider)) ?? new DistancedAgent[0];




            where IDistanceProvider is



             public interface IDistanceProvider

            double GetDistance(Agent agent);




            In the concrete use case it ends up with code like this:



             var agents = db.GetAgents();

            Func<Agent, double> getDistance = a => ws.GetDistanceMeters(a.Latitude, a.Longitude, customerLatitude, customerLongitude);

            foreach (DistancedAgent dAgent in agents.WithDistance(getDistance).OrderBy(da => da.Distance).Take(5))

            Console.WriteLine(dAgent);



            which is easy to understand and maintain and you have a setup that can be used wherever needed.






            share|improve this answer









            $endgroup$













              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "196"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );






              Yonatan Nir is a new contributor. Be nice, and check out our Code of Conduct.









              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f220650%2ffinding-the-nearest-agents-to-a-customer-using-icomparable%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              7












              $begingroup$


              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");




              You should exit your application/code block when you detect an invalid state. Here even if "No Results" is printed, the app will still run into a NullReferenceException or IndexOutOfRangeException in the next few steps. Also, talking of IndexOutOfRangeException, there is no check against if there is at least 5 agents in your db.



              Instead of creating an IComparable, you can just use linq to sort directly. But, since in your case, you also need to print out the distance (the value used for sorting), we will need to create an anonymous class to hold it:



              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");
              return;


              var nearestAgents = agents
              .Select(x => new

              x.AgentId,
              x.Latitude, x.Longitude,
              DistanceToCustomer = ws.GetDistanceMeters(x.Latitude, x.Longitude, customerLatitude, customerLongitude)
              )
              .OrderBy(x => x.DistanceToCustomer);
              foreach (var agent in nearestAgents.Take(5))

              Console.WriteLine($"agent_id: agent.AgentId distance: agent.DistanceToCustomer m");



              The .Take(5) ensures that only 5 agent will be printed out, or less.






              share|improve this answer











              $endgroup$












              • $begingroup$
                The anonymous class doesn't need the x.Latitude and x.Longitude fields.
                $endgroup$
                – 200_success
                43 mins ago















              7












              $begingroup$


              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");




              You should exit your application/code block when you detect an invalid state. Here even if "No Results" is printed, the app will still run into a NullReferenceException or IndexOutOfRangeException in the next few steps. Also, talking of IndexOutOfRangeException, there is no check against if there is at least 5 agents in your db.



              Instead of creating an IComparable, you can just use linq to sort directly. But, since in your case, you also need to print out the distance (the value used for sorting), we will need to create an anonymous class to hold it:



              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");
              return;


              var nearestAgents = agents
              .Select(x => new

              x.AgentId,
              x.Latitude, x.Longitude,
              DistanceToCustomer = ws.GetDistanceMeters(x.Latitude, x.Longitude, customerLatitude, customerLongitude)
              )
              .OrderBy(x => x.DistanceToCustomer);
              foreach (var agent in nearestAgents.Take(5))

              Console.WriteLine($"agent_id: agent.AgentId distance: agent.DistanceToCustomer m");



              The .Take(5) ensures that only 5 agent will be printed out, or less.






              share|improve this answer











              $endgroup$












              • $begingroup$
                The anonymous class doesn't need the x.Latitude and x.Longitude fields.
                $endgroup$
                – 200_success
                43 mins ago













              7












              7








              7





              $begingroup$


              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");




              You should exit your application/code block when you detect an invalid state. Here even if "No Results" is printed, the app will still run into a NullReferenceException or IndexOutOfRangeException in the next few steps. Also, talking of IndexOutOfRangeException, there is no check against if there is at least 5 agents in your db.



              Instead of creating an IComparable, you can just use linq to sort directly. But, since in your case, you also need to print out the distance (the value used for sorting), we will need to create an anonymous class to hold it:



              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");
              return;


              var nearestAgents = agents
              .Select(x => new

              x.AgentId,
              x.Latitude, x.Longitude,
              DistanceToCustomer = ws.GetDistanceMeters(x.Latitude, x.Longitude, customerLatitude, customerLongitude)
              )
              .OrderBy(x => x.DistanceToCustomer);
              foreach (var agent in nearestAgents.Take(5))

              Console.WriteLine($"agent_id: agent.AgentId distance: agent.DistanceToCustomer m");



              The .Take(5) ensures that only 5 agent will be printed out, or less.






              share|improve this answer











              $endgroup$




              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");




              You should exit your application/code block when you detect an invalid state. Here even if "No Results" is printed, the app will still run into a NullReferenceException or IndexOutOfRangeException in the next few steps. Also, talking of IndexOutOfRangeException, there is no check against if there is at least 5 agents in your db.



              Instead of creating an IComparable, you can just use linq to sort directly. But, since in your case, you also need to print out the distance (the value used for sorting), we will need to create an anonymous class to hold it:



              var agents = db.GetAgents();
              if(agents == null || agents.Count == 0)

              Console.WriteLine("No Results");
              return;


              var nearestAgents = agents
              .Select(x => new

              x.AgentId,
              x.Latitude, x.Longitude,
              DistanceToCustomer = ws.GetDistanceMeters(x.Latitude, x.Longitude, customerLatitude, customerLongitude)
              )
              .OrderBy(x => x.DistanceToCustomer);
              foreach (var agent in nearestAgents.Take(5))

              Console.WriteLine($"agent_id: agent.AgentId distance: agent.DistanceToCustomer m");



              The .Take(5) ensures that only 5 agent will be printed out, or less.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 12 hours ago

























              answered 12 hours ago









              Xiaoy312Xiaoy312

              2,9961016




              2,9961016











              • $begingroup$
                The anonymous class doesn't need the x.Latitude and x.Longitude fields.
                $endgroup$
                – 200_success
                43 mins ago
















              • $begingroup$
                The anonymous class doesn't need the x.Latitude and x.Longitude fields.
                $endgroup$
                – 200_success
                43 mins ago















              $begingroup$
              The anonymous class doesn't need the x.Latitude and x.Longitude fields.
              $endgroup$
              – 200_success
              43 mins ago




              $begingroup$
              The anonymous class doesn't need the x.Latitude and x.Longitude fields.
              $endgroup$
              – 200_success
              43 mins ago













              4












              $begingroup$

              I'd say you have the following options:




              1. Keep that new class if you think it's relevant in your business. Here, it should be important to know if the logic of calculate the distance should be on that web service (I assume that 'ws' variable means that) or within your model (i.e., the 'Agent' class).


              2. Use an anonymous class if you think you won't pass that info to another method.


              3. Use a dictionary if you think it's not relevant in your business but will pass that info to another method.

              Personally, I'd go for the first one since it's the most natural to me. By the way, I'd use LINQ's OrderBy instead of implementing the IComparable interface; again, for expressiveness.






              share|improve this answer









              $endgroup$

















                4












                $begingroup$

                I'd say you have the following options:




                1. Keep that new class if you think it's relevant in your business. Here, it should be important to know if the logic of calculate the distance should be on that web service (I assume that 'ws' variable means that) or within your model (i.e., the 'Agent' class).


                2. Use an anonymous class if you think you won't pass that info to another method.


                3. Use a dictionary if you think it's not relevant in your business but will pass that info to another method.

                Personally, I'd go for the first one since it's the most natural to me. By the way, I'd use LINQ's OrderBy instead of implementing the IComparable interface; again, for expressiveness.






                share|improve this answer









                $endgroup$















                  4












                  4








                  4





                  $begingroup$

                  I'd say you have the following options:




                  1. Keep that new class if you think it's relevant in your business. Here, it should be important to know if the logic of calculate the distance should be on that web service (I assume that 'ws' variable means that) or within your model (i.e., the 'Agent' class).


                  2. Use an anonymous class if you think you won't pass that info to another method.


                  3. Use a dictionary if you think it's not relevant in your business but will pass that info to another method.

                  Personally, I'd go for the first one since it's the most natural to me. By the way, I'd use LINQ's OrderBy instead of implementing the IComparable interface; again, for expressiveness.






                  share|improve this answer









                  $endgroup$



                  I'd say you have the following options:




                  1. Keep that new class if you think it's relevant in your business. Here, it should be important to know if the logic of calculate the distance should be on that web service (I assume that 'ws' variable means that) or within your model (i.e., the 'Agent' class).


                  2. Use an anonymous class if you think you won't pass that info to another method.


                  3. Use a dictionary if you think it's not relevant in your business but will pass that info to another method.

                  Personally, I'd go for the first one since it's the most natural to me. By the way, I'd use LINQ's OrderBy instead of implementing the IComparable interface; again, for expressiveness.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 12 hours ago









                  A Bravo DevA Bravo Dev

                  599210




                  599210





















                      0












                      $begingroup$

                      I think, I would hold on to your decorator pattern because it is more reusable than the selection with anonymous objects.



                       public class DistancedAgent : Agent

                      public DistancedAgent(Agent source, double distance)

                      AgentId = source.AgentId;
                      Latitude = source.Latitude;
                      Longitude = source.Longitude;
                      Distance = distance;


                      public double Distance get;

                      public override string ToString()

                      return $"Latitude, Longitude => Distance";




                      You could extent Agent with some converter methods:



                       public static class Extensions

                      public static DistancedAgent WithDistance(this Agent agent, Func<Agent, double> getDistance)

                      return new DistancedAgent(agent, getDistance(agent));


                      public static DistancedAgent WithDistance(this Agent agent, IDistanceProvider distanceProvider)

                      return new DistancedAgent(agent, distanceProvider.GetDistance(agent));


                      public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, Func<Agent, double> getDistance)

                      return agents?.Where(a => a != null).Select(a => a.WithDistance(getDistance)) ?? new DistancedAgent[0];


                      public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, IDistanceProvider distanceProvider)

                      return agents?.Where(a => a != null).Select(a => a.WithDistance(distanceProvider)) ?? new DistancedAgent[0];




                      where IDistanceProvider is



                       public interface IDistanceProvider

                      double GetDistance(Agent agent);




                      In the concrete use case it ends up with code like this:



                       var agents = db.GetAgents();

                      Func<Agent, double> getDistance = a => ws.GetDistanceMeters(a.Latitude, a.Longitude, customerLatitude, customerLongitude);

                      foreach (DistancedAgent dAgent in agents.WithDistance(getDistance).OrderBy(da => da.Distance).Take(5))

                      Console.WriteLine(dAgent);



                      which is easy to understand and maintain and you have a setup that can be used wherever needed.






                      share|improve this answer









                      $endgroup$

















                        0












                        $begingroup$

                        I think, I would hold on to your decorator pattern because it is more reusable than the selection with anonymous objects.



                         public class DistancedAgent : Agent

                        public DistancedAgent(Agent source, double distance)

                        AgentId = source.AgentId;
                        Latitude = source.Latitude;
                        Longitude = source.Longitude;
                        Distance = distance;


                        public double Distance get;

                        public override string ToString()

                        return $"Latitude, Longitude => Distance";




                        You could extent Agent with some converter methods:



                         public static class Extensions

                        public static DistancedAgent WithDistance(this Agent agent, Func<Agent, double> getDistance)

                        return new DistancedAgent(agent, getDistance(agent));


                        public static DistancedAgent WithDistance(this Agent agent, IDistanceProvider distanceProvider)

                        return new DistancedAgent(agent, distanceProvider.GetDistance(agent));


                        public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, Func<Agent, double> getDistance)

                        return agents?.Where(a => a != null).Select(a => a.WithDistance(getDistance)) ?? new DistancedAgent[0];


                        public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, IDistanceProvider distanceProvider)

                        return agents?.Where(a => a != null).Select(a => a.WithDistance(distanceProvider)) ?? new DistancedAgent[0];




                        where IDistanceProvider is



                         public interface IDistanceProvider

                        double GetDistance(Agent agent);




                        In the concrete use case it ends up with code like this:



                         var agents = db.GetAgents();

                        Func<Agent, double> getDistance = a => ws.GetDistanceMeters(a.Latitude, a.Longitude, customerLatitude, customerLongitude);

                        foreach (DistancedAgent dAgent in agents.WithDistance(getDistance).OrderBy(da => da.Distance).Take(5))

                        Console.WriteLine(dAgent);



                        which is easy to understand and maintain and you have a setup that can be used wherever needed.






                        share|improve this answer









                        $endgroup$















                          0












                          0








                          0





                          $begingroup$

                          I think, I would hold on to your decorator pattern because it is more reusable than the selection with anonymous objects.



                           public class DistancedAgent : Agent

                          public DistancedAgent(Agent source, double distance)

                          AgentId = source.AgentId;
                          Latitude = source.Latitude;
                          Longitude = source.Longitude;
                          Distance = distance;


                          public double Distance get;

                          public override string ToString()

                          return $"Latitude, Longitude => Distance";




                          You could extent Agent with some converter methods:



                           public static class Extensions

                          public static DistancedAgent WithDistance(this Agent agent, Func<Agent, double> getDistance)

                          return new DistancedAgent(agent, getDistance(agent));


                          public static DistancedAgent WithDistance(this Agent agent, IDistanceProvider distanceProvider)

                          return new DistancedAgent(agent, distanceProvider.GetDistance(agent));


                          public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, Func<Agent, double> getDistance)

                          return agents?.Where(a => a != null).Select(a => a.WithDistance(getDistance)) ?? new DistancedAgent[0];


                          public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, IDistanceProvider distanceProvider)

                          return agents?.Where(a => a != null).Select(a => a.WithDistance(distanceProvider)) ?? new DistancedAgent[0];




                          where IDistanceProvider is



                           public interface IDistanceProvider

                          double GetDistance(Agent agent);




                          In the concrete use case it ends up with code like this:



                           var agents = db.GetAgents();

                          Func<Agent, double> getDistance = a => ws.GetDistanceMeters(a.Latitude, a.Longitude, customerLatitude, customerLongitude);

                          foreach (DistancedAgent dAgent in agents.WithDistance(getDistance).OrderBy(da => da.Distance).Take(5))

                          Console.WriteLine(dAgent);



                          which is easy to understand and maintain and you have a setup that can be used wherever needed.






                          share|improve this answer









                          $endgroup$



                          I think, I would hold on to your decorator pattern because it is more reusable than the selection with anonymous objects.



                           public class DistancedAgent : Agent

                          public DistancedAgent(Agent source, double distance)

                          AgentId = source.AgentId;
                          Latitude = source.Latitude;
                          Longitude = source.Longitude;
                          Distance = distance;


                          public double Distance get;

                          public override string ToString()

                          return $"Latitude, Longitude => Distance";




                          You could extent Agent with some converter methods:



                           public static class Extensions

                          public static DistancedAgent WithDistance(this Agent agent, Func<Agent, double> getDistance)

                          return new DistancedAgent(agent, getDistance(agent));


                          public static DistancedAgent WithDistance(this Agent agent, IDistanceProvider distanceProvider)

                          return new DistancedAgent(agent, distanceProvider.GetDistance(agent));


                          public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, Func<Agent, double> getDistance)

                          return agents?.Where(a => a != null).Select(a => a.WithDistance(getDistance)) ?? new DistancedAgent[0];


                          public static IEnumerable<DistancedAgent> WithDistance(this IEnumerable<Agent> agents, IDistanceProvider distanceProvider)

                          return agents?.Where(a => a != null).Select(a => a.WithDistance(distanceProvider)) ?? new DistancedAgent[0];




                          where IDistanceProvider is



                           public interface IDistanceProvider

                          double GetDistance(Agent agent);




                          In the concrete use case it ends up with code like this:



                           var agents = db.GetAgents();

                          Func<Agent, double> getDistance = a => ws.GetDistanceMeters(a.Latitude, a.Longitude, customerLatitude, customerLongitude);

                          foreach (DistancedAgent dAgent in agents.WithDistance(getDistance).OrderBy(da => da.Distance).Take(5))

                          Console.WriteLine(dAgent);



                          which is easy to understand and maintain and you have a setup that can be used wherever needed.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 1 hour ago









                          Henrik HansenHenrik Hansen

                          8,86711332




                          8,86711332




















                              Yonatan Nir is a new contributor. Be nice, and check out our Code of Conduct.









                              draft saved

                              draft discarded


















                              Yonatan Nir is a new contributor. Be nice, and check out our Code of Conduct.












                              Yonatan Nir is a new contributor. Be nice, and check out our Code of Conduct.











                              Yonatan Nir is a new contributor. Be nice, and check out our Code of Conduct.














                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f220650%2ffinding-the-nearest-agents-to-a-customer-using-icomparable%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Log på Navigationsmenu

                              Creating second map without labels using QGIS?How to lock map labels for inset map in Print Composer?How to Force the Showing of Labels of a Vector File in QGISQGIS Valmiera, Labels only show for part of polygonsRemoving duplicate point labels in QGISLabeling every feature using QGIS?Show labels for point features outside map canvasAbbreviate Road Labels in QGIS only when requiredExporting map from composer in QGIS - text labels have moved in output?How to make sure labels in qgis turn up in layout map?Writing label expression with ArcMap and If then Statement?

                              Nuuk Indholdsfortegnelse Etyomologi | Historie | Geografi | Transport og infrastruktur | Politik og administration | Uddannelsesinstitutioner | Kultur | Venskabsbyer | Noter | Eksterne henvisninger | Se også | Navigationsmenuwww.sermersooq.gl64°10′N 51°45′V / 64.167°N 51.750°V / 64.167; -51.75064°10′N 51°45′V / 64.167°N 51.750°V / 64.167; -51.750DMI - KlimanormalerSalmonsen, s. 850Grønlands Naturinstitut undersøger rensdyr i Akia og Maniitsoq foråret 2008Grønlands NaturinstitutNy vej til Qinngorput indviet i dagAntallet af biler i Nuuk må begrænsesNy taxacentral mødt med demonstrationKøreplan. Rute 1, 2 og 3SnescootersporNuukNord er for storSkoler i Kommuneqarfik SermersooqAtuarfik Samuel KleinschmidtKangillinguit AtuarfiatNuussuup AtuarfiaNuuk Internationale FriskoleIlinniarfissuaq, Grønlands SeminariumLedelseÅrsberetning for 2008Kunst og arkitekturÅrsberetning for 2008Julie om naturenNuuk KunstmuseumSilamiutGrønlands Nationalmuseum og ArkivStatistisk ÅrbogGrønlands LandsbibliotekStore koncerter på stribeVandhund nummer 1.000.000Kommuneqarfik Sermersooq – MalikForsidenVenskabsbyerLyngby-Taarbæk i GrønlandArctic Business NetworkWinter Cities 2008 i NuukDagligt opdaterede satellitbilleder fra NuukområdetKommuneqarfik Sermersooqs hjemmesideTurist i NuukGrønlands Statistiks databankGrønlands Hjemmestyres valgresultaterrrWorldCat124325457671310-5