C#で2次元のリストは可能ですか?


89

多次元リストを設定したいのですが。参考までに、プレイリストアナラ​​イザに取り組んでいます。

私のプログラムは標準リストに保存するファイル/ファイルリストを持っています。各リストエントリのファイルからの1行。

次に、正規表現を使用してリストを分析し、特定の行を見つけます。行からのデータ/結果の一部を新しい多次元リストに入れる必要があります。最終的にいくつの結果/データが得られるかわからないため、多次元配列を使用できません。

これが挿入したいデータです:

リスト
(
    [0] =>リスト
        (
            [0] =>トラックID
            [1] =>名前
            [2] =>アーティスト
            [3] =>アルバム
            [4] =>再生回数
            [5] =>スキップ数

        )
    [1] =>リスト
        (
等々....

実際の例:

リスト
(
    [0] =>リスト
        (
            [0] => 2349
            [1] =>あなたの人生のプライムタイム
            [2] =>ダフトパンク
            [3] =>やっぱり人間
            [4] => 3
            [5] => 2

        )
    [1] =>リスト
        (

つまり、mlist [0] [0]は曲1からTrackIDを取得し、曲2からmlist [1] [0]を取得します。

しかし、私は多次元リストの作成に大きな問題を抱えています。これまでのところ私は思いつきました

List<List<string>> matrix = new List<List<string>>();

しかし、私は本当にこれ以上進歩していません:(

回答:


137

さて、あなたは確かにあなたが書いた場所を使うことができますList<List<string>>

List<string> track = new List<string>();
track.Add("2349");
track.Add("The Prime Time of Your Life");
// etc
matrix.Add(track);

しかし、トラックID、名前、アーティスト、アルバム、再生数、スキップ数のプロパティを使用して、トラックを表す独自のクラスを作成する代わりに、なぜそれを行うのでしょうか。その後、ちょうどがありList<Track>ます。


1
うーん、正直なところ、その方法がわかりません!プレイリストを処理するクラスだけを設定することを検討しましたが、それはより良いアイデアだと思います。
CasperT 2009年

また、最終的に作成/保存するトラックの数を知っておく必要はありませんか?
CasperT 2009年

2
いいえ、List <Track>は動的にサイズ変更されるためです。あなたは、トラックの新しいインスタンスを作成し、1トラック分のデータを解析一覧<トラック>に追加し、次の1、など解析したい
ジョンスキート

caspert、List <T>は、格納するオブジェクトの量を追跡します。あなたはリスト<T> .Count呼び出すことによって、金額にアクセスすることができます
Spoike

3
@CasperT多くの人が提案したことを行って、Trackクラスを作成してください。コードを理解/維持するのがはるかに簡単になります。トラックを文字列のリストとして表す場合、特定の属性を格納するインデックスは、トラック情報にアクセスしようとするすべてのインスタンス間で同期する必要があります。毎回実装するのが面倒になり、デバッグが不可能になります。自分のために、クラスを調べてください。:)
Alexander Kondratskiy

103

ジョンスキートはあなたがそれを行うことができます言及したList<Track>代わりに。Trackクラスは次のようになります。

public class Track {
    public int TrackID { get; set; }
    public string Name { get; set; }
    public string Artist { get; set; }
    public string Album { get; set; }
    public int PlayCount { get; set; }
    public int SkipCount { get; set; }
}

そして、List<Track>あなたがあなたとしてトラックリストを作成するには、これを行うだけです:

var trackList = new List<Track>();

トラックの追加は次のように簡単です。

trackList.add( new Track {
    TrackID = 1234,
    Name = "I'm Gonna Be (500 Miles)",
    Artist = "The Proclaimers",
    Album = "Finest",
    PlayCount = 10,
    SkipCount = 1
});

トラックへのアクセスは、インデックス付け演算子を使用して行うことができます。

Track firstTrack = trackList[0];

お役に立てれば。


4
あなたが本当に精通したいのであれば、トラックも構造体になることができます。;)
スポーク2009年

3
指定した定義ではありません...構造体のインスタンスサイズは16バイト未満にする必要があります...
Ian

@イアン:うーん。私はそれを知らなかった。そのためにMSDNドキュメントをすばやく確認したところ、構造体は16バイト未満である必要があることがわかりました。指摘してくれてありがとう。
スポーク

14
彼らはそうである必要ありません、それはただの推薦です。それほど重要ではありません。値のセマンティクスが必要な場合はstructを選択し、それ以外の場合はクラスのみを選択します。わからない場合は、クラスを使用してください。
ジェイソン

@Spoike:ループを繰り返しながらいくつかの行に存在するデータを追加したい場合に、2 forループ内でリストを使用する方法。例:for(i=0;i< length; i++) { for(j=0;j<length2;j++) {// what should be written here to get the values from a 2d array // to this 2d list } }
Sandeep

35

これは、私が見つけた最も簡単な方法です。

List<List<String>> matrix= new List<List<String>>(); //Creates new nested List
matrix.Add(new List<String>()); //Adds new sub List
matrix[0].Add("2349"); //Add values to the sub List at index 0
matrix[0].Add("The Prime of Your Life");
matrix[0].Add("Daft Punk");
matrix[0].Add("Human After All");
matrix[0].Add("3");
matrix[0].Add("2");

値を取得することはさらに簡単です

string title = matrix[0][1]; //Retrieve value at index 1 from sub List at index 0

4
以前のTrackクラスに関する提案はOPの要件に最適でしたが、このソリューションは、オブジェクトの2次元グリッドを構築するのに最適です。ありがとう!
CigarDoug、2014

2
ええ、これは私が最もシンプルでエレガントなソリューションであることがわかったものです、私が助けてくれてうれしいです!
ジョーダンラプリーズ、2014

1
シンプルで親切!ありがとうございました!
Dov Miller、

12

私が使用した別の作業は...

List<int []> itemIDs = new List<int[]>();

itemIDs.Add( new int[2] { 101, 202 } );

私が取り組んでいるライブラリには非常に形式的なクラス構造があり、2つの「関連する」intを記録する特権のためにそこに余分なものを効果的に入れたくありませんでした。

プログラマーが2項目の配列のみを入力することに依存していますが、これは一般的な項目ではないため、機能すると思います。


2

このようにして、

List<List<Object>> Parent=new  List<List<Object>>();

List<Object> Child=new List<Object>();
child.Add(2349);
child.Add("Daft Punk");
child.Add("Human");
.
.
Parent.Add(child);

別のアイテム(子)が必要な場合は、子の新しいインスタンスを作成し、

Child=new List<Object>();
child.Add(2323);
child.Add("asds");
child.Add("jshds");
.
.
Parent.Add(child);

2

2次元リストの作り方はこちら

        // Generating lists in a loop.
        List<List<string>> biglist = new List<List<string>>();

        for(int i = 1; i <= 10; i++)
        {
            List<string> list1 = new List<string>();
            biglist.Add(list1);
        }

        // Populating the lists
        for (int i = 0; i < 10; i++)
        {
            for(int j = 0; j < 10; j++)
            {
                biglist[i].Add((i).ToString() + " " + j.ToString());
            }
        }

        textbox1.Text = biglist[5][9] + "\n";

居住されていない場所にアクセスすることの危険性に注意してください。


1

私が使用した:

List<List<String>> List1 = new List<List<String>>
var List<int> = new List<int>();
List.add("Test");
List.add("Test2");
List1.add(List);
var List<int> = new List<int>();
List.add("Test3");
List1.add(List);

等しい:

List1
(
[0] => List2 // List1[0][x]
    (
        [0] => Test  // List[0][0] etc.
        [1] => Test2

    )
[1] => List2
    (
        [0] => Test3

これは私にとって役に立ちます!ありがとうございました!
Dov Miller

0

DataTableを使用することもできます。列の数とそのタイプを定義して、行を追加できます 。http://www.dotnetperls.com/datatable


コードで厳密に型指定されたクラスをサポートし、データグリッドビュー内のトラックの視覚化を簡単に構成できるように、型にDataSourceを追加するだけで、List<Track>アプローチに固執してを使用BindingSourceします。DataGridViewTrack
オリバー

同意しますが、データをすぐに表示したくない場合や、1つの場所でのみ使用するためにクラスをもう1つ作成したくない場合があるため、既存のソリューションを使用することを好みます。...これを解決するもう1つの方法を指摘したかっただけです。;)
Val

0

これは、私が取り組んでいるゲームエンジン用に少し前に作成したものです。ローカルオブジェクトの変数ホルダーとして使用されていました。基本的には通常のリストとして使用しますが、文字列名(またはID)の位置に値を保持します。少し変更すると、2Dリストが表示されます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameEngineInterpreter
{
    public class VariableList<T>
    {
        private List<string> list1;
        private List<T> list2;

        /// <summary>
        /// Initialize a new Variable List
        /// </summary>
        public VariableList()
        {
            list1 = new List<string>();
            list2 = new List<T>();
        }

        /// <summary>
        /// Set the value of a variable. If the variable does not exist, then it is created
        /// </summary>
        /// <param name="variable">Name or ID of the variable</param>
        /// <param name="value">The value of the variable</param>
        public void Set(string variable, T value)
        {
            if (!list1.Contains(variable))
            {
                list1.Add(variable);
                list2.Add(value);
            }
            else
            {
                list2[list1.IndexOf(variable)] = value;
            }
        }

        /// <summary>
        /// Remove the variable if it exists
        /// </summary>
        /// <param name="variable">Name or ID of the variable</param>
        public void Remove(string variable)
        {
            if (list1.Contains(variable))
            {
                list2.RemoveAt(list1.IndexOf(variable));
                list1.RemoveAt(list1.IndexOf(variable));
            }
        }

        /// <summary>
        /// Clears the variable list
        /// </summary>
        public void Clear()
        {
            list1.Clear();
            list2.Clear();
        }

        /// <summary>
        /// Get the value of the variable if it exists
        /// </summary>
        /// <param name="variable">Name or ID of the variable</param>
        /// <returns>Value</returns>
        public T Get(string variable)
        {
            if (list1.Contains(variable))
            {
                return (list2[list1.IndexOf(variable)]);
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// Get a string list of all the variables 
        /// </summary>
        /// <returns>List string</string></returns>
        public List<string> GetList()
        {
            return (list1);
        }
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.