Apakah Daftar 2 dimensi dimungkinkan di c #?

89

Saya ingin membuat daftar multidimensi. Sebagai referensi, saya sedang mengerjakan penganalisis daftar putar.

Saya memiliki file / file-list, yang disimpan oleh program saya dalam daftar standar. Satu baris dari file di setiap entri daftar.

Saya kemudian menganalisis daftar dengan ekspresi reguler untuk menemukan baris tertentu. Beberapa data / hasil dari garis perlu dimasukkan ke dalam daftar multidimensi baru ; karena saya tidak tahu berapa banyak hasil / data yang akan saya dapatkan, saya tidak dapat menggunakan array multidimensi.

Berikut data yang ingin saya masukkan:

Daftar
(
    [0] => Daftar
        (
            [0] => ID Trek
            [1] => Nama
            [2] => Artis
            [3] => Album
            [4] => Hitungan Permainan
            [5] => Lewati Hitungan

        )
    [1] => Daftar
        (
Dan seterusnya....

Contoh Nyata:

Daftar
(
    [0] => Daftar
        (
            [0] => 2349
            [1] => Waktu Utama Hidup Anda
            [2] => Punk Bajingan
            [3] => Bagaimanapun, Manusia
            [4] => 3
            [5] => 2

        )
    [1] => Daftar
        (

Jadi ya, mlist [0] [0] akan mendapatkan TrackID dari lagu 1, mlist [1] [0] dari lagu 2, dll.

Tetapi saya mengalami masalah besar saat membuat daftar multidimensi. Sejauh ini saya telah menemukan

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

Tapi saya belum benar-benar memiliki lebih banyak kemajuan :(

CasperT
sumber

Jawaban:

139

Nah, Anda pasti bisa menggunakan List<List<string>>tempat Anda kemudian menulis:

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

Tetapi mengapa Anda melakukan itu daripada membuat kelas Anda sendiri untuk merepresentasikan lagu, dengan properti Track ID, Name, Artist, Album, Play Count, dan Skip Count? Maka miliki saja List<Track>.

Jon Skeet
sumber
1
Hmm, sejujurnya saya tidak yakin bagaimana melakukan itu! Saya melihat menyiapkan kelas untuk menangani daftar putar saja, tapi saya rasa itu adalah ide yang lebih baik.
CasperT
Juga, bukankah perlu mengetahui berapa banyak trek yang pada akhirnya akan saya buat / simpan?
CasperT
2
Tidak, karena Daftar <Track> masih berukuran dinamis. Anda akan mengurai data untuk satu track, membuat instance Track baru, menambahkannya ke List <Track>, lalu mengurai yang berikutnya, dll.
Jon Skeet
caspert, List <T> melacak jumlah objek yang disimpannya untuk Anda. Anda dapat mengakses jumlah tersebut dengan menelepon List <T> .Count
Spoike
3
@CasperT Harap lakukan apa yang disarankan banyak orang dan buatlah Trackkelas. Akan lebih mudah untuk memahami / memelihara kode. Jika Anda merepresentasikan trek sebagai daftar string, maka indeces tempat Anda menyimpan atribut tertentu harus disinkronkan di semua contoh saat Anda mencoba mengakses informasi trek. Ini akan menjadi membosankan untuk diterapkan setiap kali dan tidak mungkin untuk melakukan debug. Tolong, demi Anda sendiri, lihatlah kelas-kelas. :)
Alexander Kondratskiy
103

Seperti yang disebutkan Jon Skeet, Anda dapat melakukannya dengan a List<Track>. Kelas Track akan terlihat seperti ini:

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; }
}

Dan untuk membuat daftar trek sebagai List<Track>Anda cukup lakukan ini:

var trackList = new List<Track>();

Menambahkan trek bisa sesederhana ini:

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

Mengakses trek dapat dilakukan dengan operator pengindeksan:

Track firstTrack = trackList[0];

Semoga ini membantu.

Spoike
sumber
4
Jika Anda ingin benar-benar paham, Track juga bisa menjadi struct. ;)
Spoike
3
Tidak dengan definisi yang Anda berikan ... Structs harus memiliki ukuran instance kurang dari 16bytes ...
Ian
@Ian: Hmm. Saya tidak menyadarinya. Cepat memeriksa doc MSDN untuk itu dan ternyata struct harus kurang dari 16 byte. Terima kasih telah menunjukkannya.
Spoike
14
Tidak perlu , itu hanya rekomendasi. Itu tidak terlalu penting; pilih struct jika Anda membutuhkan nilai semantik jika tidak, cukup kelas. Jika Anda tidak tahu, gunakan kelas.
jason
35

Ini adalah cara termudah yang saya temukan untuk melakukannya.

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");

Untuk mengambil nilai lebih mudah

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

pekerjaan lain yang pernah saya gunakan adalah ...

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

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

Perpustakaan yang saya kerjakan memiliki struktur kelas yang sangat formal dan saya tidak menginginkan barang tambahan di sana secara efektif untuk hak istimewa merekam dua int 'terkait'.

Bergantung pada programmer yang hanya memasukkan 2 item array tetapi karena itu bukan item umum, saya pikir itu berfungsi.

paul jamison
sumber
2

Anda juga bisa..melakukan dengan cara ini,

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);

jika Anda membutuhkan item lain (anak), buat instance anak baru,

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

Berikut cara membuat list 2 dimensi

        // 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";

Waspadai bahaya mengakses lokasi yang tidak berpenghuni.

Ben
sumber
1

Saya menggunakan:

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);

itu sama dengan:

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

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

Anda juga dapat menggunakan DataTable - Anda dapat menentukan jumlah kolom dan tipenya, lalu menambahkan baris http://www.dotnetperls.com/datatable

Val
sumber
Lebih baik tetap berpegang pada List<Track>pendekatan dan gunakan a BindingSource, dengan hanya menambahkan DataSource ke DataGridViewjenis Anda Trackuntuk mendukung kelas yang diketik dengan kuat dalam kode dan visualisasi trek yang mudah dikonfigurasi dalam tampilan kisi data.
Oliver
Setuju, tetapi terkadang Anda tidak ingin menampilkan datanya secara instan dan Anda tidak ingin membuat satu kelas lagi hanya untuk digunakan di satu tempat saja, jadi saya lebih suka menggunakan solusi yang sudah ada. ... Hanya ingin menunjukkan satu cara lagi untuk menyelesaikan ini! ;)
Val
0

Ini sedikit sesuatu yang saya buat beberapa waktu lalu untuk mesin game yang sedang saya kerjakan. Itu digunakan sebagai pemegang variabel objek lokal. Pada dasarnya, Anda menggunakannya sebagai daftar normal, tetapi memegang nilai pada posisi apa pun nama string (atau ID). Sedikit modifikasi, dan Anda akan mendapatkan daftar 2D Anda.

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);
        }
    }
}
Joe Horrell
sumber