0

I have three arrays like below:

   string[] shapeTypes = {"circle", "triangle", "square" };
   string[] shapeColor = { "red", "blue", "orange" };
   double[] shapeArea = { 20, 5, 4 };

I have to sort shapes by the value of their area (ascending order). For example the sorted arrays would be:

   shapeTypes = {"square", "triangle", "circle" };
   shapeColor = { "orange", "blue", "red" };
   shapeArea = { 4,5,20};

I tried Array.Sort method so far but it looks like it isn't working.

Array.Sort(shapeArea);
Array.Sort(shapeArea, shapeTypes);

Screenshot

Am I doing something wrong, or is there another way to sort the arrays?

6
  • 5
    It's not clear what the relationship between Types, Color and Area is. You may consider whether or not you can use a class. If you use a class, see Use the IComparable and IComparer interfaces in Visual CSharp. Commented Mar 2, 2023 at 15:56
  • 2
    Please post all your code as copy-pasted text, not image(s). Having said that - if you first call Sort only with shapeArea (as the screenshot suggests) this array will be already in a different order and the second call to Sort will not have to modify it. You probably want only the 2nd call. Commented Mar 2, 2023 at 15:58
  • 1
    What you probably want is to have a class Shape with Type, Color and Area properties. That allows you to use LINQ and simply do shapes = shapes.OrderBy(x => x.Area). Commented Mar 2, 2023 at 15:59
  • Are your 3 arrays related by their indexes ? I mean, do you have 'red circle 20', 'blue triangle 5' and 'orange square 4' ? If yes, considere using a class or a record with 3 attributes to represents a shape. Commented Mar 2, 2023 at 16:00
  • Sort() sorts an array alphabetically by default. You are not using a comparer interface or anything like it to tell the method how to sort or the criteria to do it, so it sorted alphabetically. Commented Mar 2, 2023 at 16:02

5 Answers 5

1

The problem is that you call Sort twice:
After this 1st call:

Array.Sort(shapeArea);

shapeArea will be sorted, i.e.: {4, 5, 20).

Then the 2nd call:

Array.Sort(shapeArea, shapeTypes);

Will not change anything because shapeArea is already sorted.

Instead you should use only the 2nd call to sort both shapeArea and shapeTypes in synch.

Note:
Having said that, if you want to keep these 3 properties (type, color and area) in synch, a better approach would be to create a class to hold them.
Then use either Linq, or Array.Sort with a comparator for sorting (shown below).

Code example:

using System;

public class Program
{
    class Shape
    {
        public Shape(string type, string color, double area)
        {
            Type = type;
            Color = color;
            Area = area;
        }

        public string Type { get; set; }
        public string Color { get; set; }
        public double Area { get; set; }
    }

    public static void Main(String[] args)
    {
        Shape[] shapes =
        {
            new Shape("circle", "red", 20),
            new Shape("triangle", "blue", 5),
            new Shape("square", "orange", 4),
        };

        // Sort by area via a comparator:
        Array.Sort(shapes, (a, b) => a.Area.CompareTo(b.Area));
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Instead of having a separate array for each property, create a class combining all these properties. Then create a single array of this class:

// Naive implementation
public class Shape
{
    public string Type { get; set; }
    public string Color { get; set; }
    public double Area { get; set; }
}

This allows you to sort like this:

Shape[] shapes = {
    new Shape { Type = "circle", Color = "red", Area = 20 },
    new Shape { Type = "triangle", Color = "blue", Area = 5 },
    new Shape { Type = "square", Color = "orange", Area = 4 }
};

Array.Sort(shapes, (a, b) => a.Area.CompareTo(b.Area));

A better way to represent the shapes and colors is to use enums:

public enum ShapeType
{
    Circle,
    Triangle,
    Square
}

public enum ShapeColor
{
    Red,
    Blue,
    Green,
    Orange,
    // ...
}

And to implement the class like this

public class Shape
{
    public ShapeType Type { get; set; }
    public ShapeColor Color { get; set; }
    public double Area { get; set; }
}

A more advanced technique is to use inheritance to create different shapes:

public abstract class Shape
{
    public Color Color { get; set; }
    public abstract double Area { get; }
}

public class Circle : Shape
{
    public double Radius { get; set; }

    public override double Area => Radius * Radius * Math.PI;
}

public class Square : Shape
{
    public double Length { get; set; }

    public override double Area => Length * Length;
}

public class Triangle : Shape
{
    public double Height { get; set; }
    public double Base{ get; set; }

    public override double Area => Height * Base / 2;
}

I also use the Color Struct from the System.Drawing Namespace

Arrays have a fixed size. Using lists allows you to add, replace or remove shapes later. Example:

List<Shape> shapes = new() {
    new Circle { Color = Color.Red, Radius = 2.52 },
    new Triangle { Color = Color.Blue, Base = 4, Height = 2.5 },
    new Square { Color = Color.Orange, Length = 2 }
};

// Add a shape later
shapes.Add(new Circle { Color = Color.Yellow, Radius = 3 });

shapes.Sort((a, b) => a.Area.CompareTo(b.Area));

Comments

1

Here is a method that sorts three arrays of different types, based on the values in the first array. It allocates internally an int[] array, with size equal to the first array.

/// <summary>
/// Sorts three arrays, one contains the keys and the others contain
/// the corresponding items, based on the keys in the first array.
/// </summary>
public static void Sort<TKey, T1, T2>(TKey[] keys, T1[] items1, T2[] items2,
    IComparer<TKey> comparer = default)
{
    ArgumentNullException.ThrowIfNull(keys);
    ArgumentNullException.ThrowIfNull(items1);
    ArgumentNullException.ThrowIfNull(items2);
    if (items1.Length < keys.Length)
        throw new ArgumentException("Array too small.", nameof(items1));
    if (items2.Length < keys.Length)
        throw new ArgumentException("Array too small.", nameof(items2));
    comparer ??= Comparer<TKey>.Default;

    // Create an array of incremental indices (zero based).
    int[] indices = new int[keys.Length];
    for (int i = 0; i < indices.Length; i++) indices[i] = i;

    // Sort the indices according to the keys.
    Array.Sort<int>(indices, (x, y) => comparer.Compare(keys[x], keys[y]));

    // Sort all the arrays according to the indices.
    for (int i = 0; i < indices.Length - 1; i++)
    {
        int k = indices[i];
        while (k < i) k = indices[k];
        if (k == i) continue;
        // Swap the items in the positions i and k.
        Swap(keys, i, k);
        Swap(items1, i, k);
        Swap(items2, i, k);
    }

    static void Swap<T>(T[] array, int x, int y)
    {
        T temp = array[x];
        array[x] = array[y];
        array[y] = temp;
    }
}

Usage example:

Sort(shapeArea, shapeTypes, shapeColor);

Online demo.

I've used the same technique with the indices in this question: Sort array of integer-triples in C#.

Comments

0

You can use SortedList<TKey,TValue>

SortedList<string, double> shapeTypeAreas = new SortedList<string, double>();
 
shapeTypeAreas.Add("circle",20);
shapeTypeAreas.Add("triangle", 5);
shapeTypeAreas.Add("square", 4); 
foreach( KeyValuePair<string, string> kvp in shapeTypeAreas )
{
  Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}

Comments

0

You need to inspect the shapeTypes array after the Sort. Check the following:

        string[] shapeTypes = { "circle", "triangle", "square" };
        string[] shapeColor = { "red", "blue", "orange" };
        double[] shapeArea = { 20, 5, 4 };

        Array.Sort(shapeArea, shapeTypes);

        Console.WriteLine(shapeTypes);
        Console.WriteLine(shapeArea);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.