fc2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »配列操作
このページの記事一覧

【C#】配列やコレクションの IsNullOrEmpty  


 ああ、そう言えば「配列 や List の TryGetValue」やったのに、もっとよく使うもの忘れてたな~、と思い出したので、とても簡単なものだが、あると非常に便利ものなので一応書いておこう。

 これは文字列で string.IsNullOrEmpy() をよく使うので、同じような感覚で、配列や List 等が null または 空 (Count = 0) でないかを調べるものがあれば、便利なのにな~と思ったので、昔作ったものだ。実際にあまりに頻繁に使うので、標準関数かと思い違いしてしまうほどだ(笑)。

 まぁたぶん、皆似たようなものを作ってる気がするが、まだ勉強しはじめたばかりの人もいるかもなので(面白いことに、もう随分たくさんの記事を書いたが、上級者向けより、初心者向けの記事の方がアクセスは多いものなのだ)、役に立つかはわからないが、とりあえず書いておこう。



●配列やコレクションの IsNullOrEmpty
using System;
using System.Collections.Generic;

public static class Extensions //名前は任意
{
/// <summary>
/// コレクションが null または Count = 0 か?
/// 2021/07/11 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-399.html
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection">調べるコレクション</param>
/// <returns>true : null または Count = 0</returns>
public static bool IsNullOrEmpty<T>(this ICollection<T> collection)
{
return collection == null || collection.Count == 0;
}

/// <summary>
/// 配列が null または Length = 0 か?
/// 2021/07/11 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-399.html
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array">調べる配列</param>
/// <returns>true : null または Length = 0</returns>
public static bool IsNullOrEmpty<T>(this T[] array)
{
return (array == null || array.Length == 0);
}
}

●メインコード例
using System;
using System.Collections.Generic;

var emptyList = new List();
var list = new List() { 1, 2, 3 };
Console.WriteLine("emptyList : " + emptyList.IsNullOrEmpty());
Console.WriteLine("list : " + list.IsNullOrEmpty());

var emptyDic = new Dictionary();
var dic = new Dictionary()
{
{ "hoge", 100 },
{ "fuga", 200 },
};
Console.WriteLine("emptyDic : " + emptyDic.IsNullOrEmpty());
Console.WriteLine("dic : " + dic.IsNullOrEmpty());

var emptySet = new HashSet();
var set = new HashSet() { "hoge", "fuga" };
Console.WriteLine("emptySet : " + emptySet.IsNullOrEmpty());
Console.WriteLine("set : " + set.IsNullOrEmpty());

var emptyArray = new string[0];
var array = new string[] { "apple", "banana", "candy" };
Console.WriteLine("emptyArray : " + emptyArray.IsNullOrEmpty());
Console.WriteLine("array : " + array.IsNullOrEmpty());

emptyList : True
list : False
emptyDic : True
dic : False
emptySet : True
set : False
emptyArray : True
array : False

 これも本当になんてことないものなんだけどね。できればこれも標準関数に欲しいくらい(笑)。

 私はこれに NOT値(反転値)を求める IsExist() みたいな定義も加えて、よく使っている。

●!IsNullOrEmpty() (反転値) を返す IsExist()
//null でない、かつ Count > 0
public static bool IsExist(this ICollection collection) => !collection.IsNullOrEmpty();

//null でない、かつ Length > 0
public static bool IsExist(this T[] array) => !array.IsNullOrEmpty();

 これは「if (!list.IsNullOrEmpty())」みたいなものを「if (list.IsExist())」と「!」を入れないで済むので、少しわかりやすくなるので重宝してる。まぁ、日本語でも「〇〇でなくはない」みたいな否定の否定って意味がわかりずらいからね。その辺は好みで(笑)。






(関連記事)
【C#】配列 や List の TryGetValue
【Unity】【C#】配列・リストのシャッフル
【C#】2次元配列(ジャグ配列・多次元配列)のソート
【C#】多次元配列とジャグ配列(2次元配列)のサイズ(長さ)、相互変換など
【C#】配列やListなどの中身(要素)を見る拡張メソッド Dump


関連記事
スポンサーサイト



category: C#

thread: プログラミング

janre: コンピュータ

tag: C#ライブラリ  C#リファレンス  配列操作  連想配列 
tb: 0   cm: --

【C#】HashSet や Dictionary の AddRange  


 前回に引き続き「標準関数にあったら良いな」シリーズ(笑)。

 List には後から、要素を複数追加する AddRange() というメソッドがあるが、残念ながら、HashSetDictionary には無い。しかし、意外と複数の要素を追加したいときってあるんだよね。そんな時に便利な拡張メソッド。



●HashSet, Dictionary の AddRange
using System;
using System.Collections.Generic;

public static class Extensions //名前は任意
{
/// <summary>
/// 複数の要素を追加する(同じ値は上書きとなる)
/// ※null であっても、必ず生成される
/// 2021/06/13 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-398.html
/// </summary>
/// <param name="set">追加先</param>
/// <param name="collection">追加ソース</param>
/// <returns></returns>
public static HashSet<T> AddRange<T>(this HashSet<T> set, IEnumerable<T> collection)
{
if (set == null)
set = new HashSet<T>();

if (collection != null)
{
foreach (var item in collection)
set.Add(item);
}
return set;
}

/// <summary>
/// 複数のキーと値ペアを追加する(同じキーは上書きとなる)
/// ※null であっても、必ず生成される.
/// 2021/06/13 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-398.html
/// </summary>
/// <param name="dst">追加先</param>
/// <param name="src">追加ソース</param>
/// <returns></returns>
public static Dictionary<K, V> AddRange<K, V>(this Dictionary<K, V> dst, Dictionary<K, V> src)
{
if (dst == null)
dst = new Dictionary<K, V>();

if (src != null)
{
foreach (var item in src)
dst[item.Key] = item.Value;
}
return dst;
}
}

●メインコード例
using System;
using System.Collections.Generic;
using System.Linq;

var aSet = new HashSet<int>(Enumerable.Range(0, 5));
Console.WriteLine("Before : " + aSet.Dump());

var bSet = new HashSet<int>(Enumerable.Range(10, 5));
aSet.AddRange(bSet);
Console.WriteLine("After : " + aSet.Dump());

var cSet = new HashSet<int>(aSet).AddRange(bSet);
Console.WriteLine("c = a + b : " + cSet.Dump());

var aDic = new Dictionary<int, string>()
{
{ 0, "a" },
{ 1, "b" },
{ 2, "c" },
};
Console.WriteLine("Before : " + aDic.Dump());

var bDic = new Dictionary<int, string>()
{
{ 10, "x" },
{ 11, "y" },
{ 12, "z" },
};
aDic.AddRange(bDic);
Console.WriteLine("After : " + aDic.Dump());

var cDic = new Dictionary<int, string>(aDic).AddRange(bDic);
Console.WriteLine("c = a + b : " + cDic.Dump());

Before : [0, 1, 2, 3, 4]
After : [0, 1, 2, 3, 4, 10, 11, 12, 13, 14]
c = a + b : [0, 1, 2, 3, 4, 10, 11, 12, 13, 14]
Before : [[0, a], [1, b], [2, c]]
After : [[0, a], [1, b], [2, c], [10, x], [11, y], [12, z]]
c = a + b : [[0, a], [1, b], [2, c], [10, x], [11, y], [12, z]]

 要素をダンプしている Dump() は以前の記事からコピペして欲しい。

 少し標準関数の List.AddRange() と違うのは、void を返してるのではなく、コレクションを返してる所かな。こうすると、メソッドチェーンみたいにできるので、new と同時にいくつかの別コレクションを追加できたりするので、便利だ。

 とても簡単なものだけど、これもあると非常に有用なんだよね。私は結構大きなシステムを自作してるけど、大きくなるほど、こういった便利関数は欠かせなくなる(毎回似たような処理を書くのは大変な物量になるため)。実はプログラミングってこういう小さな工夫の積み重ねなんだよね(笑)。



 「これくらいのものなら、LINQ で書けばいいんじゃないの?」と思うかも知れないが、私はあまりオススメしない。というのは LINQ はそれなりにコストがかかるのと、GC を発生しやすいので、頻繁に使われるかも知れない拡張メソッド等は、割とベタな書き方をした方が速いし、GC も制御しやすいからだ。まぁ、string 系の処理はどのみち GC が発生するので使うこともあるが(しかし、できる限り StringBuilder を使う方が良い)、LINQ はどちらかというと、ランタイムで1回きりの初期化処理とか、頻繁には使わない処理用かな。特に Unity のような毎フレーム更新するような処理には気をつけて使った方が良いね。

コストのかかる操作を避ける





(関連記事)
【C#】配列 や List の TryGetValue
【C#】配列やListなどの中身(要素)を見る拡張メソッド Dump
【Unity】【C#】配列・リストのシャッフル
【C#】2次元配列(ジャグ配列・多次元配列)のソート
【C#】多次元配列とジャグ配列(2次元配列)のサイズ(長さ)、相互変換など


関連記事

category: C#

thread: プログラミング

janre: コンピュータ

tag: C#ライブラリ  C#リファレンス  配列操作  連想配列 
tb: 0   cm: --

【C#】配列 や List の TryGetValue  


 今回はとても簡単なもので、意外と便利なもの。

 配列や List を扱う上で注意すべき点は、インデクス範囲外(Index was out of range) と null かどうかだが、毎回 null チェックや範囲外チェックをやるのは少し面倒である。

 Dictionary ではキーを用いて値の取得を試みる TryGetValue があるが、これと同じ様なものがあったら便利なのにな~、と思ったので作ってみた。



●配列, List の TryGetValue
using System;
using System.Collections.Generic;

public static class Extensions //名前は任意
{
/// <summary>
/// 配列 の TryGetValue
/// ・配列自体が null or インデクスが範囲外のとき false
/// 2021/05/17 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-397.html
/// </summary>
/// <typeparam name="T">要素の型</typeparam>
/// <param name="array">対象の配列</param>
/// <param name="idx">取得するインデクス</param>
/// <param name="value">取得成功したときの値</param>
/// <returns>true = 取得成功</returns>
public static bool TryGetValue<T>(this T[] array, int idx, out T value)
{
value = default(T);
if (array == null || idx < 0 || array.Length <= idx)
return false;

value = array[idx];
return true;
}

/// <summary>
/// List の TryGetValue
/// ・List 自体が null or インデクスが範囲外のとき false
/// 2021/05/17 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-397.html
/// </summary>
/// <typeparam name="T">要素の型</typeparam>
/// <param name="list">対象の List</param>
/// <param name="idx">取得するインデクス</param>
/// <param name="value">取得成功したときの値</param>
/// <returns>true = 取得成功</returns>
public static bool TryGetValue<T>(this List<T> list, int idx, out T value)
{
value = default(T);
if (list == null || idx < 0 || list.Count <= idx)
return false;

value = list[idx];
return true;
}
}

●メインコード例
using System;
using System.Collections.Generic;
using System.Linq;

int max = 50;
var array = Enumerable.Range(0, max).ToArray(); //0~49 まで
var list = Enumerable.Range(0, max).ToList(); //0~49 まで

int idxA = 25;
if (array.TryGetValue(idxA, out var resultA))
{
Console.WriteLine($"result value (Array) = {resultA}");
}
else
{
Console.WriteLine($"idx = {idxA} : Index was out of range or null (Array)");
}

int idxL = 50;
if (list.TryGetValue(idxL, out var resultL))
{
Console.WriteLine($"result value (List) = {resultL}");
}
else
{
Console.WriteLine($"idx = {idxL} : Index was out of range or null (List)");
}

//var res = list[100]; //Index was out of range

result value (Array) = 25
idx = 50 : Index was out of range or null (List)

 本当になんてことないものなんだけどね。できれば標準関数に欲しいくらい(笑)。

 例えば範囲外のインデクスのとき、予め Fallback 的な値を決めておく等、とても簡潔に書ける。

●例:範囲内なら配列の値を返し、範囲外なら 0 を返す
int[] arr = {0,1,2,3,4};
int GetOrFallback(int idx) => arr.TryGetValue(idx, out var res) ? res : 0;




 ところで少し話はずれるが、Dictionary で値の取得を試みるとき、どうやっているだろうか?

 例えば以下のような感じに書けると思うが、① と ② では実行速度が結構違う。

ContainsKey を用いてから取得
if (dic.ContainsKey(key))  //dic は Dictionary とする
{
var res = dic[key];
//ここで res を使った処理
}

TryGetValue で取得
if (dic.TryGetValue(key, out var res))  //dic は Dictionary とする
{
//ここで res を使った処理
}

 ① と ② は同じ結果にはなるが、実は実行速度は ① の方が約2倍かかる(遅い)。

 理由は簡単で、① は ContainsKey で1度 get, インデクサ(dic[key]) でもう1度 get の計2回 get (取得)するからである。TryGetValue は1回で済むので、その分速い。

 ほんのちょっとしたことでも、実行速度を改善できたりするので、特に高速なメインループ処理を実現したい時などに思い出してみると良い(Unity みたいな、毎フレーム回す処理には、徹底すれば意外と効果がある=アルゴリズム変更しない限りでは「手数を減らす」のが直接速度改善に繋がる)。





(関連記事)
【Unity】【C#】配列・リストのシャッフル
【C#】2次元配列(ジャグ配列・多次元配列)のソート
【C#】多次元配列とジャグ配列(2次元配列)のサイズ(長さ)、相互変換など
【C#】配列やListなどの中身(要素)を見る拡張メソッド Dump


関連記事

category: C#

thread: プログラミング

janre: コンピュータ

tag: C#ライブラリ  C#リファレンス  配列操作 
tb: 0   cm: --

【C#】ソート済み List を動的に作る拡張メソッド  


 今回は二分探索によるリスト処理の高速化できる拡張メソッドを作ってみよう。

 普段、何気なく List に値を Add したり、Remove したりしてはいないだろうか?
 また検索というと、標準で使える List.ContainsList.FindList.FindIndex 等や、Linq の FistOrDefault などを使う機会も多いだろう。
 しかし、これらは逐次探索(O(n))のため、要素数に比例して、検索速度は遅くなる。特に1000を超えるデータを頻繁に扱うとなると、かなり実行速度に影響が出る。

 そのような場合、ケースにもよるのだが、List に追加する要素の順番は必要ないとき、または ID のように昇順で並んでいる方が便利なとき等、常に List をソート済みにしておくと、二分探索(BinaraySearch)が使えるようになる。
 二分探索のオーダーは O(log n) のため、要素が多くなっても、検索速度はそれほど落ちない。

 もし、ただの1回のみのソートで良いのなら、全て要素を追加した後に、単純に List.Sort や Linq の OrderBy を使う方が良いだろう。しかし、頻繁にデータを追加したり、削除したりする場合は、動的にソート済みリストを作っていく拡張メソッドを作っておくと便利だ。



●動的にソート済みリストに要素を追加、削除していく拡張メソッド
using System.Collections.Generic;

public static class Extentions //※名前は任意
{
/// <summary>
/// 昇順で要素を追加する
/// 2021/02/02 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-392.html
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">対象リスト</param>
/// <param name="value">追加する要素</param>
/// <returns>true = 新規追加 / false = 既存あり(重複で追加)</returns>
public static bool AddSorted<T>(this List<T> list, T value)
{
int idx = list.BinarySearch(value);
if (idx < 0)
{
list.Insert(~idx, value);
return true;
}
list.Insert(idx, value);
return false;
}

/// <summary>
/// 昇順で要素をユニーク追加する
/// 2021/02/02 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-392.html
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">対象リスト</param>
/// <param name="value">追加する要素</param>
/// <returns>true = 新規追加 / false = 既存あり(追加しない)</returns>
public static bool AddSortedUniq<T>(this List<T> list, T value)
{
int idx = list.BinarySearch(value);
if (idx < 0)
{
list.Insert(~idx, value);
return true;
}
return false;
}

/// <summary>
/// 昇順のリストから要素を削除
/// 2021/02/02 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-392.html
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">対象リスト</param>
/// <param name="value">削除する要素</param>
/// <returns>true = 削除した / false = 既存なし(削除失敗)</returns>
public static bool RemoveSorted<T>(this List<T> list, T value)
{
int idx = list.BinarySearch(value);
if (idx >= 0)
{
list.RemoveAt(idx);
return true;
}
return false;
}
}

●メインコード例
using System;
using System.Collections.Generic;

string[] array =
{
"Apple", "Banana", "Candy", "Donuts", "Egg", "Fish", "Candy", "Egg"
};

array.Shuffle(); //※Shuffle は以前の記事を参照
Console.WriteLine(array.Dump()); //※Dump は以前の記事を参照

var list1 = new List(array.Length);
var list2 = new List(array.Length);
foreach (var item in array)
{
list1.AddSorted(item); //昇順で追加
list2.AddSortedUniq(item); //昇順でユニーク追加
}

Console.WriteLine("list1 : " + list1.Dump()); //※Dump は以前の記事を参照
Console.WriteLine("list2 : " + list2.Dump()); //※Dump は以前の記事を参照

//昇順リストから削除
list1.RemoveSorted("Candy");
list1.RemoveSorted("Egg");
Console.WriteLine("list1 (Removed) : " + list1.Dump()); //※Dump は以前の記事を参照
Console.WriteLine("list2 (Removed) : " + list2.Dump()); //※Dump は以前の記事を参照

//二分探索
int idx1 = list1.BinarySearch("Candy");
Console.WriteLine($"idx1 = {idx1}");
int idx2 = list1.BinarySearch("Egg");
Console.WriteLine($"idx2 = {idx2}");

[Banana, Egg, Apple, Candy, Egg, Donuts, Fish, Candy]
list1 : [Apple, Banana, Candy, Candy, Donuts, Egg, Egg, Fish]
list2 : [Apple, Banana, Candy, Donuts, Egg, Fish]
list1 (Removed) : [Apple, Banana, Candy, Donuts, Egg, Fish]
list2 (Removed) : [Apple, Banana, Candy, Donuts, Egg, Fish]
idx1 = 2
idx2 = 4

 DumpShuffle の拡張メソッドは以前に作ったものだ。

Dump の拡張メソッド
Shuffle の拡張メソッド

 どのように追加されているかに注目して欲しい。常に昇順に並び替えたリストと同義となるため、追加するたびソート(List.Sort)する必要はもちろん無い。
 取得するときは List.BinarySearch が使えるので、ちょっとやそっと要素数が増えた所で、検索速度が落ちることはない(実際に 100000 [10万] くらいの要素数があっても、検索速度は速い)。

 また、この例ではコンストラクタで new List(int capacity) を使っているが、これは予め格納できるサイズを確保しておくコンストラクタだ。色々なコードを見ていても、ほとんどが引数なし new List() で使われているが、実はこれはとても重要だ。と言うのは、List の様な動的に増やせるコレクションというのは、現在格納できるサイズを超えると、メモリの再割当てをし(サイズ拡大)、コピーする動作を頻繁に繰り返すからだ。要素が多くなると、負荷がかかるのは言うまでもない。はじめからわかっている、または想定できるなら、capacity を指定した方が、要素を追加するとき、無駄な処理が走らない(Dictionary なども同じ)。

 以下は Unity 上で、毎フレーム逐次検索(List.ContainsList.Find)していた箇所を、二分探索探索に置き換えただけのもので、パフォーマンスを比較してみたものだ。
 青い部分はスクリプトの負荷で、激減していることが分かる。実際にほんの数行置き換えただけなのだが、圧倒的なパフォーマンスを出すことができることさえある(この時は約5倍以上になった)。



 ここでは、List.BinarySearch しか使ってないが、以前に紹介した LowerBounds, UpperBounds も併用して使うと良いだろう。

【C#】 LowerBound, UpperBound (二分探索)

 二分探索は上手く使えば、かなりのパフォーマンス改善になる場合があることも少なくない。開発現場では簡潔だからか Linq が使われることが多い気がするが、実はとても遅く、GCを発生させ易いので、利用には注意が必要だ(要は使い処である)。

Unity のパフォーマンスに関する推奨事項 - コストのかかる操作を避ける
LINQとfor, ListとArray(配列)での実行速度を比較してみる
【Unity】CPUプロファイラでパフォーマンスを改善する - GCの発生要因を減らす






(関連記事)
【C#】配列やListなどの中身(要素)を見る拡張メソッド Dump
【Unity】【C#】配列・リストのシャッフル
【C#】二分探索の実装(範囲インデクス指定実装)
【C#】 LowerBound, UpperBound (二分探索)
【Ruby】二分探索, lower_bound, upper_bound
【Unity】【C#】LINQとfor, ListとArray(配列)での実行速度を比較してみる
【C#】連想配列(Dictionary)を値 or キーでソート
【C#】2次元配列(ジャグ配列・多次元配列)のソート
【C#】多次元配列とジャグ配列(2次元配列)のサイズ(長さ)、相互変換など


関連記事

category: C#

thread: プログラミング

janre: コンピュータ

tag: C#ライブラリ  配列操作  二分探索 
tb: 0   cm: --

【C#】配列やListなどの中身(要素)を見る拡張メソッド Dump  


 今回はデバッグに便利な拡張メソッドを作ってみよう。

 C# では静的配列も List などのコレクション系も IEnumerable という interface が実装されている。

 このインターフェイスは、簡単な理解ではイテレータ(ループなどで順次要素を取り出す)機能みたいなものだが、お陰で1つの拡張メソッドを定義しておけば、簡単に型違いの配列や List などを扱える便利なものでもある(Java でも Iterator というものがあるが、プリミティブ型には使えないため、少し不便)。

 またこの IEnumerableLINQ と組み合わせると簡潔に書けることも多いため、覚えておくと色々便利だ。

 ここでは簡単だが、利用頻度も高い拡張メソッドを定義しておこう。



●配列や List (Collections) などの中身(要素)を見る Dump
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public static class Extensions //※名前は任意
{
/// <summary>
/// コレクションのダンプ
/// 2021/01/11 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-391.html
/// </summary>
public static string Dump<T>(this IEnumerable<T> source)
{
return (source == null) ? "[]"
: ("[" + string.Join(", ", source.Select(e => e.ToString()).ToArray()) + "]");
}

/// <summary>
/// コレクションのダンプ(string.Format 付き)
/// 2021/01/11 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-391.html
/// </summary>
public static string Dump<T>(this IEnumerable<T> source, string format)
{
return (source == null) ? "[]"
: ("[" + string.Join(", ", source.Select(e => string.Format(format, e)).ToArray()) + "]");
}
}

●メインコード例
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

var nums = Enumerable.Range(0, 20).ToArray(); //int[]
var list = new List<string>()
{
"hoge", "fuga", "piyo"
};

Console.WriteLine(nums.Dump());
Console.WriteLine(list.Dump());

//Format 付きテスト
var sqrt = Enumerable.Range(1, 10).Select(e => Math.Sqrt(e)); //IEnumerable<double>
Console.WriteLine(sqrt.Dump("{0:F3}")); //小数点3桁

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[hoge, fuga, piyo]
[1.000, 1.414, 1.732, 2.000, 2.236, 2.449, 2.646, 2.828, 3.000, 3.162]

 string format の引数を持つオーバーロードは float や double 等、浮動小数点の型で使うと便利だろう。

 一覧を囲む文字は "["~"]" で固定してしまってるが、必要ならオーバーロード作るのも良い。

 配列(Array) や IEnumerable<T> をそのまま使えるので、利用範囲は広いと思う。

 ちなみに、文字列配列を結合するのに string.Join を使っているが、LINQEnumerable.Aggregate を使う手もある。しかし、実装速度は劣るようだ。

//string.Join の代わりに Enumerable.Aggregate を使っても良いが、実行速度は遅い
source.Select(e => e.ToString()).Aggregate((s, e) => s + ", " + e)

 どちらか言うと、デバッグにしか使わないと思うが、あまり巨大な配列などではないなら、開発中は常に色々ダンプして、中身をチェックした方が不具合も見つけやすい。

 こういうちょっとしたものが、意外とデバッグを楽にしてくれたりするんだよね(笑)。





(関連記事)
【Unity】【C#】LINQとfor, ListとArray(配列)での実行速度を比較してみる
【C#】連想配列(Dictionary)を値 or キーでソート
【C#】2次元配列(ジャグ配列・多次元配列)のソート
【C#】多次元配列とジャグ配列(2次元配列)のサイズ(長さ)、相互変換など


関連記事

category: C#

thread: プログラミング

janre: コンピュータ

tag: C#ライブラリ  配列操作 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop