2020年10月14日
川俣晶の縁側ソフトウェアC# コーディング How Tototal 959 count

【入門級】ユニークさの保証・その値は配列に一つだけか?

Written By: 川俣 晶連絡先

配列に1の値は1つしかないことを保証したい §

 整数の配列があるとします。

 中に入っている値に1が一つしかないことを確認するのはどうすれば良いでしょうか?

 サンプルソースのCheckSingle1は大人しく一致する要素の数を数えています。

 サンプルソースのCheckSingle2はSingleOrDefaultメソッドに【1つしかない】という保証を実行させています。

 サンプルソースのCheckSingle3はSingleOrDefaultメソッドの代わりにSingleメソッドを使用しています。

 では、3つの方法のうちどれが最善でしょうか?

 実は例外に依存しないCheckSingle1の方式が最も効率が良くソースも短くなります。

 Singleメソッド/SingleOrDefaultメソッドは、例外が本当にイレギュラーな事態にのみ起こる場合に使用すると良いでしょう。しかし、最大で1つしかないことが保証されているソースから取得する場合は、First/FirstOrDefaultメソッドの利用も検討すべきです。これは【1つしかにない】ことを保証しない代わりに高速です。

罠の数々 §

  • Singleメソッド/SingleOrDefaultメソッドは便利そうに見える高機能メソッドなのだが、本当に必要とされることは少なく、使い所が本当に難しい。たいていFirst/FirstOrDefaultメソッドで用が足りる。数を確認したければCountメソッドで良い
  • Singleメソッドの場合のみ、0個の場合と2個以上の場合を区別できない。機能的にやや劣っている。

参考リンク §

Enumerable.Count メソッド

Enumerable.SingleOrDefault メソッド

Enumerable.Single メソッド

 機能もそっくり、名前もそっくりのSingle メソッドとSingleOrDefault メソッドは具体的に何が違うのだろうか。上記のリンクから辿って違いを調べてみよう。

リポジトリ §

https://github.com/autumn009/cshowto

single §

using System;

using System.Linq;

class Program

{

    private static void CheckSingle1(int[] ar)

    {

        foreach (var item in ar) Console.Write($"{item} ");

        int c = ar.Count(c => c == 1);

        if (c == 0)

            Console.WriteLine("に1はありません。");

        else if (c == 1)

            Console.WriteLine("に1は1つだけあります。");

        else

            Console.WriteLine("に1は2個以上です。");

    }

    private static void CheckSingle2(int[] ar)

    {

        foreach (var item in ar) Console.Write($"{item} ");

        try

        {

            int r = ar.SingleOrDefault(c => c == 1);

            if (r == 0)

                Console.WriteLine("に1はありません。");

            else if (r == 1)

                Console.WriteLine("に1は1つだけあります。");

            else

                Console.WriteLine("不明です。");

        }

        catch (InvalidOperationException)

        {

            Console.WriteLine("に1は2個以上です。");

        }

    }

    private static void CheckSingle3(int[] ar)

    {

        foreach (var item in ar) Console.Write($"{item} ");

        try

        {

            ar.Single(c => c == 1);

            Console.WriteLine("に1は1つだけあります。");

        }

        catch (InvalidOperationException)

        {

            Console.WriteLine("に1は無いか2個以上です。");

        }

    }

    static void Main()

    {

        int[] ar1 = { 2, 2, 3 };

        int[] ar2 = { 1, 2, 3 };

        int[] ar3 = { 1, 2, 1 };

        CheckSingle1(ar1);

        CheckSingle1(ar2);

        CheckSingle1(ar3);

        CheckSingle2(ar1);

        CheckSingle2(ar2);

        CheckSingle2(ar3);

        CheckSingle3(ar1);

        CheckSingle3(ar2);

        CheckSingle3(ar3);

    }

}

実行結果

2 2 3 に1はありません。

1 2 3 に1は1つだけあります。

1 2 1 に1は2個以上です。

2 2 3 に1はありません。

1 2 3 に1は1つだけあります。

1 2 1 に1は2個以上です。

2 2 3 に1は無いか2個以上です。

1 2 3 に1は1つだけあります。

1 2 1 に1は無いか2個以上です。

Facebook

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?
キーワード【 川俣晶の縁側ソフトウェアC# コーディング How To
【C# コーディング How To】の次のコンテンツ
2020年
10月
15日
【入門級】文字列をbyte配列に直してまた文字列に戻す
3days 0 count
total 2765 count
【C# コーディング How To】の前のコンテンツ
2020年
10月
12日
【入門級】ソートが失敗するとき
3days 0 count
total 1067 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

https://mag.autumn.org/tb.aspx/20201014101851
サイトの表紙【C# コーディング How To】の表紙【C# コーディング How To】のコンテンツ全リスト 【C# コーディング How To】の入手全リスト 【C# コーディング How To】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.