C # ile 2 boyutlu Listeler mümkün müdür?


91

Çok boyutlu bir liste oluşturmak istiyorum. Referans olarak, bir oynatma listesi analizörü üzerinde çalışıyorum.

Programımın standart bir listeye kaydettiği bir dosya / dosya listem var. Her liste girişindeki dosyadan bir satır.

Daha sonra belirli satırları bulmak için listeyi normal ifadelerle analiz ederim. Çizgilerden elde edilen verilerin / sonuçların bir kısmının yeni bir çok boyutlu listeye konulması gerekmektedir ; Kaç sonuç / veri ile sonuçlanacağımı bilmediğim için çok boyutlu bir dizi kullanamıyorum.

İşte eklemek istediğim veriler:

Liste
(
    [0] => Liste
        (
            [0] => Parça Kimliği
            [1] => İsim
            [2] => Sanatçı
            [3] => Albüm
            [4] => Oynatma Sayısı
            [5] => Sayımı Atla

        )
    [1] => Liste
        (
Ve bunun gibi....

Gerçek Örnek:

Liste
(
    [0] => Liste
        (
            [0] => 2349
            [1] => Hayatınızın En Güzel Zamanı
            [2] => Daft Punk
            [3] => Sonuçta İnsan
            [4] => 3
            [5] => 2

        )
    [1] => Liste
        (

Yani evet, mlist [0] [0] 1. şarkıdan TrackID, 2. şarkıdan mlist [1] [0] vb. Alır.

Ancak çok boyutlu bir liste oluştururken büyük sorunlar yaşıyorum. Şimdiye kadar buldum

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

Ama gerçekten daha fazla ilerleme kaydetmedim :(

Yanıtlar:


140

Pekala ,List<List<string>> daha sonra yazacağınız yeri kesinlikle kullanabilirsiniz :

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

Peki Parça Kimliği, Ad, Sanatçı, Albüm, Çalma Sayısı ve Atlama Sayımı özellikleriyle bir parçayı temsil etmek için kendi sınıfınızı oluşturmak yerine neden bunu yapasınız? O zaman bir List<Track>.


1
Hmm, gerçekten bunu nasıl yapacağımdan emin değilim! Sadece çalma listesi yönetimi için bir sınıf oluşturmaya baktım, ama sanırım bu daha iyi bir fikir.
CasperT

Ayrıca, sonunda kaç parça oluşturacağımı / depolayacağımı bilmem gerekmiyor mu?
CasperT

2
Hayır, çünkü <Track> Listesi hala dinamik olarak boyutlandırılmıştır. Bir parça için verileri ayrıştırır, yeni bir Track örneği oluşturur, <Track> Listesine ekler ve ardından bir sonrakini ayrıştırırsınız, vb.
Jon Skeet

caspert, <T> Listesi sizin için sakladığı nesnelerin miktarını takip eder.
Tutara

3
@CasperT Lütfen birçoklarının önerdiklerini yapın ve bir Tracksınıf oluşturun. Kodu anlamak / sürdürmek çok daha kolay olacaktır. Bir parçayı dizelerin listesi olarak temsil ediyorsanız, belirli bir özniteliği sakladığınız iç kısımların, parça bilgilerine erişmeye çalıştığınız tüm örneklerde senkronize edilmesi gerekecektir . Her seferinde uygulamak yorucu olacak ve hata ayıklaması imkansız hale gelecektir. Lütfen kendi iyiliğiniz için derslere bakın. :)
Alexander Kondratskiy

103

As Jon Skeet bir ile bunu yapabilirsiniz sözü List<Track>yerine. Track sınıfı şunun gibi görünür:

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

Ve bir parça listesi oluşturmak için List<Track>basitçe şunu yapın:

var trackList = new List<Track>();

Parça eklemek şu kadar basit olabilir:

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

Parçalara erişim, indeksleme operatörü ile yapılabilir:

Track firstTrack = trackList[0];

Bu yardımcı olur umarım.


4
Gerçekten anlayışlı olmak istiyorsanız, Track bir yapı da olabilir. ;)
Spoike

3
Verdiğiniz tanımla değil ... Yapılar 16 bayttan daha küçük bir örnek boyutuna sahip olmalıdır ...
Ian

@ Ian: Hmm. Bunun farkında değildim. Bunun için hızlı bir şekilde MSDN belgesine bakıldı ve yapıların 16 bayttan daha az olması gerektiği ortaya çıktı. Gösterdiğiniz için teşekkürler.
Spoike

14
Onlar yok gerek bu sadece bir öneri var, olmaya. Gerçekten o kadar önemli değil; değer semantiğine ihtiyacınız varsa yapı seçin, aksi halde sadece sınıf. Bilmiyorsanız, bir sınıf kullanın.
jason

35

Bunu yapmanın en kolay yolu bu.

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

Değerleri almak daha da kolay

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

12

çevresinde kullandığım başka bir çalışma da ...

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

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

Üzerinde çalıştığım kütüphane çok resmi bir sınıf yapısına sahip ve iki 'ilgili' girişi kaydetme ayrıcalığı için orada etkili bir şekilde fazladan şeyler istemedim.

Programcının yalnızca 2 öğeli bir dizi girmesine dayanır, ancak bu ortak bir öğe olmadığı için çalıştığını düşünüyorum.


2

Ayrıca .. bu şekilde yapabilirsiniz,

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

başka bir öğeye (alt öğeye) ihtiyacınız varsa, yeni bir child örneği oluşturun,

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

2

İşte 2 boyutlu bir liste nasıl yapılır

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

Nüfusun bulunmadığı bir yere erişim tehlikesinin farkında olun.


1

Kullandım:

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

bu eşittir:

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

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

0

Ayrıca DataTable'ı da kullanabilirsiniz - daha sonra sütunların sayısını ve türlerini tanımlayabilir ve ardından http://www.dotnetperls.com/datatable satırları ekleyebilirsiniz.


List<Track>Yaklaşıma daha iyi bağlı kalın ve kodda güçlü bir şekilde yazılmış sınıfları desteklemek ve izlerin veri ızgarası görünümünde kolayca yapılandırılması BindingSourceiçin bir DataSource DataGridViewtürüne ekleyerek a kullanın Track.
Oliver

Kabul edildi, ancak bazen verileri anında görüntülemek istemiyorsunuz ve sadece tek bir yerde kullanmak için bir sınıf daha oluşturmak istemiyorsunuz, bu yüzden mevcut bir çözümü kullanmayı tercih ediyorum. ... Bunu çözmenin bir yolunu daha göstermek istedim! ;)
Val

0

İşte bir süre önce üzerinde çalıştığım bir oyun motoru için yaptığım küçük bir şey. Yerel nesne değişkeni tutucusu olarak kullanıldı. Temel olarak, onu normal bir liste olarak kullanırsınız, ancak dize adı (veya kimliği) ne olursa olsun, değeri konumunda tutar. Biraz değişiklik yaptıktan sonra 2D listeniz olacak.

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);
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.