รายการ 2 มิติเป็นไปได้ใน c # หรือไม่?


91

ฉันต้องการตั้งค่ารายการหลายมิติ สำหรับการอ้างอิงฉันกำลังทำงานกับตัววิเคราะห์เพลย์ลิสต์

ฉันมีไฟล์ / รายการไฟล์ซึ่งโปรแกรมของฉันบันทึกไว้ในรายการมาตรฐาน หนึ่งบรรทัดจากไฟล์ในแต่ละรายการ

จากนั้นฉันจะวิเคราะห์รายการด้วยนิพจน์ทั่วไปเพื่อค้นหาบรรทัดเฉพาะ ข้อมูล / ผลลัพธ์บางส่วนจากบรรทัดจะต้องใส่ลงในรายการหลายมิติใหม่ เนื่องจากฉันไม่รู้ว่าจะได้ผลลัพธ์ / ข้อมูลจำนวนเท่าใดฉันจึงไม่สามารถใช้อาร์เรย์หลายมิติได้

นี่คือข้อมูลที่ฉันต้องการแทรก:

รายการ
(
    [0] => รายการ
        (
            [0] => Track ID
            [1] => ชื่อ
            [2] => ศิลปิน
            [3] => อัลบั้ม
            [4] => จำนวนการเล่น
            [5] => ข้ามการนับ

        )
    [1] => รายการ
        (
และอื่น ๆ ....

ตัวอย่างจริง:

รายการ
(
    [0] => รายการ
        (
            [0] => 2349
            [1] => ช่วงเวลาสำคัญของชีวิตคุณ
            [2] => Daft Punk
            [3] => มนุษย์หลังจากทั้งหมด
            [4] => 3
            [5] => 2

        )
    [1] => รายการ
        (

ใช่แล้ว mlist [0] [0] จะได้รับ TrackID จากเพลง 1, mlist [1] [0] จากเพลง 2 เป็นต้น

แต่ฉันมีปัญหาใหญ่ในการสร้างรายการหลายมิติ จนถึงตอนนี้ฉันได้มากับ

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

แต่ฉันยังไม่มีความคืบหน้ามากนัก :(

คำตอบ:


140

แน่นอนคุณสามารถใช้List<List<string>>ที่ที่คุณจะเขียน:

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

แต่ทำไมคุณถึงทำเช่นนั้นแทนที่จะสร้างคลาสของคุณเองเพื่อแสดงแทร็กด้วยคุณสมบัติ Track ID, Name, Artist, Album, Play Count และ Skip Count จากนั้นก็มีไฟล์List<Track>.


1
อืมฉันไม่แน่ใจว่าจะทำอย่างไร! ฉันดูการตั้งค่าคลาสสำหรับการจัดการเพลย์ลิสต์เพียงอย่างเดียว แต่ฉันคิดว่านั่นเป็นความคิดที่ดีกว่า
CasperT

นอกจากนี้ไม่จำเป็นต้องรู้ว่าในที่สุดฉันจะสร้าง / จัดเก็บแทร็กกี่เพลง?
CasperT

2
ไม่เนื่องจากรายการ <Track> ยังคงมีขนาดแบบไดนามิก คุณจะแยกวิเคราะห์ข้อมูลสำหรับแทร็กหนึ่งสร้างอินสแตนซ์ใหม่ของแทร็กเพิ่มในรายการ <Track> แล้วแยกวิเคราะห์รายการถัดไป ฯลฯ
Jon Skeet

caspert รายการ <T> จะติดตามจำนวนวัตถุที่เก็บไว้สำหรับคุณ คุณสามารถเข้าถึงจำนวนเงินได้โดยโทรไปที่ List <T> .Count
Spoike

3
@CasperT โปรดทำสิ่งที่หลายคนแนะนำและสร้างTrackชั้นเรียน จะง่ายกว่ามากในการทำความเข้าใจ / รักษาโค้ด หากคุณแสดงแทร็กเป็นรายการสตริงดัชนีที่คุณจัดเก็บแอตทริบิวต์เฉพาะจะต้องซิงโครไนซ์กับอินสแตนซ์ทั้งหมดที่คุณพยายามเข้าถึงข้อมูลแทร็ก มันจะน่าเบื่อในการใช้งานในแต่ละครั้งและเป็นไปไม่ได้ที่จะแก้ไข โปรดดูในชั้นเรียนเพื่อประโยชน์ของคุณเอง :)
Alexander Kondratskiy

103

ดังที่Jon Skeetกล่าวถึงคุณสามารถทำได้โดยใช้ a 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
หากคุณต้องการที่จะเข้าใจจริงๆ Track อาจเป็นโครงสร้าง ;)
Spoike

3
ไม่ใช่กับคำจำกัดความที่คุณให้มา ... โครงสร้างควรมีขนาดอินสแตนซ์น้อยกว่า 16 ไบต์ ...
เอียน

@ เอียน: อืม. ฉันไม่รู้เรื่องนั้น ตรวจสอบเอกสาร MSDN อย่างรวดเร็วและปรากฎว่าโครงสร้างต้องน้อยกว่า 16 ไบต์ ขอบคุณที่ชี้ให้เห็น
Spoike

14
พวกเขาไม่จำเป็นต้องเป็นเพียงคำแนะนำ มันไม่ได้สำคัญอะไรมาก เลือกโครงสร้างหากคุณต้องการความหมายเชิงคุณค่ามิฉะนั้นก็แค่คลาส หากคุณไม่ทราบให้ใช้ชั้นเรียน
สัน

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

12

วิธีอื่นที่ฉันใช้คือ ...

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

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

ห้องสมุดที่ฉันกำลังทำงานอยู่มีโครงสร้างชั้นเรียนที่เป็นทางการมากและฉันก็ไม่ได้ต้องการสิ่งพิเศษในนั้นอย่างมีประสิทธิภาพสำหรับสิทธิพิเศษในการบันทึก 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

0

คุณยังสามารถใช้ DataTable - คุณสามารถกำหนดจำนวนคอลัมน์และประเภทจากนั้นเพิ่มแถว http://www.dotnetperls.com/datatable


ยึดList<Track>แนวทางนี้ให้ดีขึ้นและใช้ a BindingSourceโดยเพียงแค่เพิ่ม DataSource ให้DataGridViewกับประเภทของคุณTrackเพื่อรองรับคลาสที่พิมพ์มากในโค้ดและง่ายต่อการกำหนดค่าการแสดงภาพแทร็กภายในมุมมองตารางข้อมูล
Oliver

เห็นด้วย แต่บางครั้งคุณไม่ต้องการแสดงข้อมูลทันทีและคุณไม่ต้องการสร้างคลาสขึ้นมาอีกเพียงเพื่อใช้ในที่เดียวดังนั้นฉันจึงชอบใช้โซลูชันที่มีอยู่ ... แค่อยากจะชี้ให้เห็นอีกหนึ่งวิธีในการแก้ปัญหานี้! ;)
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.