noutarins
@noutarins (nou tarins)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

データに対する処理をそのデータの持つ番号順に行いたい

解決したいこと

C# Unity VS です。
データに対する処理をそのデータの持つ番号順に行いたいです。

public class StudentDate1
{
   string name = aikawa;
   int number = 1;
}

public class StudentDate2
{
   string name = tanaka;
   int number = 15;
}

public class StudentDate3
{
   string name = sato;
   int number = 13;
}

例えば上のような三つのデータに対して、「 numberの小さい順にnameを表示するメソッド」を作りたいときどのようにすればいいのでしょうか?

0

3Answer

上のデータ例を見る限り、StudentDate1~3は一種類のクラスで表現できる?
であれば、
1)データを配列で受け取る
2)配列をnumberをキーに昇順にソート
3)ソートしたデータのnameを表示する
と処理するメソッドを作ればOKかと思います。

sample.cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    public class StudentData
    {
        public string Name { get; init; }
        public int Number { get; init; }
    }

    internal class Program
    {
        /// <summary>
        /// numberの小さい順にnameを表示する
        /// </summary>
        /// <param name="students"></param>
        public static void ShowStudentName( IEnumerable<StudentData> students )
        {
            foreach ( var student in students.OrderBy( x => x.Number ) ) {
                Console.WriteLine( student.Name );
            }
        }

        private static void Main()
        {
            var students = new[] {
                new StudentData { Name = "aikawa", Number =  1 },
                new StudentData { Name = "tanaka", Number = 15 },
                new StudentData { Name = "sato",   Number = 13 },
            };

            ShowStudentName( students );
        }
    }
}
2Like

<別解>
StudentDate1~3を一種類のクラスで表現できない場合は、
共通部分を親クラスにくくり出すやりかたでOKかと思います。

sample.cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    public abstract class StudentData
    {
        public string Name { get; init; }   // StudentData1~3共通のプロパティ
        public int Number { get; init; }    // StudentData1~3共通のプロパティ
    }

    public class StudentData1 : StudentData
    {
        public double XXX { get; init; }    // StudentData1固有のプロパティ
    }

    public class StudentData2 : StudentData
    {
        public string YYY { get; init; }    // StudentData2固有のプロパティ
    }

    public class StudentData3 : StudentData
    {
        public object ZZZ { get; init; }    // StudentData3固有のプロパティ
    }

    internal class Program
    {
        /// <summary>
        /// numberの小さい順にnameを表示する
        /// </summary>
        /// <param name="students"></param>
        public static void ShowStudentName( IEnumerable<StudentData> students )
        {
            foreach ( var student in students.OrderBy( x => x.Number ) ) {
                Console.WriteLine( student.Name );
            }
        }

        private static void Main()
        {
            var students = new StudentData[] {
                new StudentData1 { Name = "aikawa", Number =  1, XXX = 100.0 },
                new StudentData2 { Name = "tanaka", Number = 15, YYY = "yyy" },
                new StudentData3 { Name = "sato",   Number = 13, ZZZ = new object() },
            };

            ShowStudentName( students );
        }
    }
}
0Like

Comments

  1. @noutarins

    Questioner

    本当にありがとうございます、やってみます。

@TackKaiware さんのものでまったく問題ないですが、速度を重視したい場合は処理をさせるたびに毎回ソートするのが不利になります。(Unityということなのでそういう用途もありそう)
そこを改善したいなら「整列済みリスト」を作っておくと効率的です。
リストの内容や並び順がちょくちょく変わる場合は無駄が多くなりますけど。

@TackKaiwareさんの2つめのやつがベース
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    public abstract class StudentData
    {
        public string Name { get; init; }   // StudentData1~3共通のプロパティ
        public int Number { get; init; }    // StudentData1~3共通のプロパティ

        /// <summary>
        /// ソート済みリストを作成
        /// </summary>
        /// <param name="source">ソート前のリスト</param>
        /// <returns>ソート済みリスト</returns>
        /// <remarks>リスト作成後にNumberを変更してはいけない</remarks>
        public static SortedList<int, StudentData> CreateSortedList(IEnumerable<StudentData> source)
        {
            var list = new SortedList<int, StudentData>(source.Count());
            foreach (var item in source)
            {
                list.Add(item.Number, item);
            }
            return list;
        }
    }

    public class StudentData1 : StudentData
    {
        public double XXX { get; init; }    // StudentData1固有のプロパティ
    }

    public class StudentData2 : StudentData
    {
        public string YYY { get; init; }    // StudentData2固有のプロパティ
    }

    public class StudentData3 : StudentData
    {
        public object ZZZ { get; init; }    // StudentData3固有のプロパティ
    }

    internal class Program
    {
        /// <summary>
        /// リスト順にnameを表示する
        /// </summary>
        /// <param name="sortedStudents"></param>
        public static void ShowStudentName(IEnumerable<StudentData> sortedStudents)
        {
            foreach (var student in sortedStudents)
            {
                Console.WriteLine(student.Name);
            }
        }

        private static void Main()
        {
            var students = new StudentData[] {
                new StudentData1 { Name = "aikawa", Number =  1, XXX = 100.0 },
                new StudentData2 { Name = "tanaka", Number = 15, YYY = "yyy" },
                new StudentData3 { Name = "sato",   Number = 13, ZZZ = new object() },
            };

            //ソート済みリストを作成
            var sortedSutdents = StudentData.CreateSortedList(students);

            ShowStudentName(sortedSutdents);
        }
    }
}
0Like

Comments

  1. @noutarins

    Questioner

    ありがとうございます!こっちも頑張って理解してみます!

Your answer might help someone💌