none
C#2013のListの要素のシフト RRS feed

  • 質問

  • 以下のようなクラスを作成し,Listの中に値を代入しています.

        public class ADC1VM
        {
            public class ADC1PointCollection : List<ADC1Point>
            {
                private const int TOTAL_POINTS = 5000;

                public ADC1PointCollection()
                    : base(TOTAL_POINTS) 
                {
                }
            }

            public class ADC1Point
            {
                //public DateTime Date { get; set; }
                public long DataCount { get; set; }

                public double A1 { get; set; }

                public ADC1Point(long dc, double d)
                {
                    this.DataCount = dc;
                    this.A1 = d;

                }
            }
        }

    使用する時は

    public DDD.ADC1VM.ADC1PointCollection ADC1PointCollection;

    と宣言し,

    ADC1PointCollection.Add(new DDD.ADC1VM.ADC1Point(data_count, m));

    のように値(m)を代入しています.

    データ数が一定数を超えたら,Listの値を全て先頭側に1要素ずらしてから,最後の要素に新しい値を入れたいと考えています.

    上記のような動作を行うためにはどのような処理を記述すれば良いでしょうか?

    お分かりになられる方がいらっしゃいましたら,何卒ご教授よろしくお願い致します.

    2017年6月3日 4:56

回答

  • 単純に、追加の前に一定数を超えていたら先頭を削除してから追加というのではだめなのでしょうか

    if (ADC1PointCollection.Count >= ADC1PointCollection.Capacity)
    {
        ADC1PointCollection.RemoveAt(0);
    }
    ADC1PointCollection.Add(new DDD.ADC1VM.ADC1Point(data_count, m));

    追加するのがIList<T>.AddでなくADC1PointCollection.Addとはっきりしているときのみであれば、newで隠したAddを作って、

    public class ADC1PointCollection : System.Collections.Generic.List<ADC1Point>
    {
        private const int TOTAL_POINTS = 5000;
    
        public ADC1PointCollection()
            : base(TOTAL_POINTS)
        {
        }
    
        public new void Add(ADC1Point item)
        {
            if (this.Count == this.Capacity)
            {
                this.RemoveAt(0);
            }
            base.Add(item);
        }
    }

    とすることも可能ですが、まちがえてList<T>.Addするとおかしくなります。


    あるいは追加する時に判定をするIList<T>を作ってしまうという方法もあります。

    public class List<T> : System.Collections.ObjectModel.Collection<T>
    {
        public int MaxCount { get; private set; }
    
        public List(int maxCount) : base(maxCount)
        {
            if (Count <= 0) throw new ArgumentOutOfRangeException("maxCount");
            this.MaxCount = maxCount;
        }
    
        protected override void InsertItem(int index, T item)
        {
            if (index == this.Count && this.Count == this.MaxCount)
            {
                this.RemoveAt(0);
                index--;
            }
            base.InsertItem(index, item);
        }
    }

    データ数が一定数を超えて、かつ途中にInsertの場合はどうするのでしょう?
    末尾にしか追加せず、かつインデックスで途中の要素にアクセスしないならQueue<T>の方が良いかも。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2017年6月3日 6:33
    • 回答としてマーク protecyamyam 2017年6月3日 7:10
    2017年6月3日 6:29

すべての返信

  • 単純に、追加の前に一定数を超えていたら先頭を削除してから追加というのではだめなのでしょうか

    if (ADC1PointCollection.Count >= ADC1PointCollection.Capacity)
    {
        ADC1PointCollection.RemoveAt(0);
    }
    ADC1PointCollection.Add(new DDD.ADC1VM.ADC1Point(data_count, m));

    追加するのがIList<T>.AddでなくADC1PointCollection.Addとはっきりしているときのみであれば、newで隠したAddを作って、

    public class ADC1PointCollection : System.Collections.Generic.List<ADC1Point>
    {
        private const int TOTAL_POINTS = 5000;
    
        public ADC1PointCollection()
            : base(TOTAL_POINTS)
        {
        }
    
        public new void Add(ADC1Point item)
        {
            if (this.Count == this.Capacity)
            {
                this.RemoveAt(0);
            }
            base.Add(item);
        }
    }

    とすることも可能ですが、まちがえてList<T>.Addするとおかしくなります。


    あるいは追加する時に判定をするIList<T>を作ってしまうという方法もあります。

    public class List<T> : System.Collections.ObjectModel.Collection<T>
    {
        public int MaxCount { get; private set; }
    
        public List(int maxCount) : base(maxCount)
        {
            if (Count <= 0) throw new ArgumentOutOfRangeException("maxCount");
            this.MaxCount = maxCount;
        }
    
        protected override void InsertItem(int index, T item)
        {
            if (index == this.Count && this.Count == this.MaxCount)
            {
                this.RemoveAt(0);
                index--;
            }
            base.InsertItem(index, item);
        }
    }

    データ数が一定数を超えて、かつ途中にInsertの場合はどうするのでしょう?
    末尾にしか追加せず、かつインデックスで途中の要素にアクセスしないならQueue<T>の方が良いかも。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 編集済み gekkaMVP 2017年6月3日 6:33
    • 回答としてマーク protecyamyam 2017年6月3日 7:10
    2017年6月3日 6:29
  • ご回答ありがとうございます.

    最初にご提示いただいたコードで問題なく動作いたしました.

    その他の方法はまだ理解が追い付かないですが,勉強していきたいと思います,

    ありがとうございました.

    • 回答としてマーク protecyamyam 2017年6月3日 7:10
    • 回答としてマークされていない protecyamyam 2017年6月3日 7:10
    2017年6月3日 7:10