How to simplify my code? (Search for minimum and maximum coordinates in a list of strings)

I have code that looks for minimum and maximum values ​​in a list of strings. I need this to find the center of the rectangle that borders my complex drawing.

My piece of code looks like this:

if (line.X1 < Min.X) Min.X = line.X1;
if (line.Y1 < Min.Y) Min.Y = line.Y1;
if (line.X2 < Min.X) Min.X = line.X2;
if (line.Y2 < Min.Y) Min.Y = line.Y2;

I don't like this ugly copy-paste code. How can I simplify this / make it more elegant?

+3
source share
4 answers

Given the following populated variable:

List<Line> lines;

Get X values ​​and Y values:

var xValues = lines.SelectMany(line => new[] { line.X1, line.X2 });
var yValues = lines.SelectMany(line => new[] { line.Y1, line.Y2 });

Then get the minimum and maximum of each of them:

var leastX = xValues.Min();
var greatestX = xValues.Max();
var leastY = yValues.Min();
var greatestY = yValues.Max();

Please note that this code is not verified.

+1
source

How about something like this:

var xList = {line.X1, line.X2, ...};
var yList = {line.Y1, line.Y2, ...};

Min.X = xList.Min();
Min.Y = yList.Min();
+3
source

, Math.Min:

Min.X = Math.Min(line.X2, Math.Min(line.X1, Min.X));
Min.Y = Math.Min(line.Y2, Math.Min(line.Y1, Min.Y));
+1

The design of your classes already has some duplication; your class definition of Linea is Pointduplicated in X1, X2etc.

If your design looks something like this:

class Point
{
    public int X { get; set; }
    public int Y { get; set; }
}

class Line
{
    public Point Start { get; set; }
    public Point End { get; set; }

    public IEnumerable<Point> Endpoints
    {
        get
        {
            return new[] { Start, End };
        }
    }
}

You can implement your calculations as follows:

class ExtremetiesDeterminer
{
    private IEnumerable<Point> endpoints;

    public Line DetermineBoundaries(IEnumerable<Line> complicatedShapeLines)
    {
        endpoints = complicatedShapeLines.SelectMany(line => line.Endpoints);

        return new Line
        {
            Start = FindExtremety(Enumerable.Min),
            End = FindExtremety(Enumerable.Max)
        };
    }

    private Point FindExtremety(
        SingleAxisExtremetyDeterminer findSingleAxisExtremety)
    {
        return new Point
        {
            X = findSingleAxisExtremety(endpoints, point => point.X),
            Y = findSingleAxisExtremety(endpoints, point => point.Y)
        };
    }

    public delegate int SingleAxisExtremetyDeterminer(
        IEnumerable<Point> points, Func<Point, int> getCoordinate);
}

Note that this reduces duplication. You probably want to tweak this depending on how it interacts with the rest of your code.

+1
source

All Articles