Danh sách 2 chiều có khả thi trong c # không?


89

Tôi muốn thiết lập một danh sách nhiều chiều. Để tham khảo, tôi đang làm việc trên trình phân tích danh sách phát.

Tôi có một tệp / danh sách tệp, chương trình của tôi lưu trong một danh sách chuẩn. Một dòng từ tệp trong mỗi mục nhập danh sách.

Sau đó, tôi phân tích danh sách với các biểu thức chính quy để tìm các dòng cụ thể. Một số dữ liệu / kết quả từ các dòng cần được đưa vào danh sách đa chiều mới ; vì tôi không biết tôi sẽ kết thúc với bao nhiêu kết quả / dữ liệu, nên tôi không thể sử dụng mảng đa chiều.

Đây là dữ liệu tôi muốn chèn:

Danh sách
(
    [0] => Danh sách
        (
            [0] => ID theo dõi
            [1] => Tên
            [2] => Nghệ sĩ
            [3] => Album
            [4] => Lượt chơi
            [5] => Bỏ qua số lượng

        )
    [1] => Danh sách
        (
Và như thế....

Ví dụ thực tế:

Danh sách
(
    [0] => Danh sách
        (
            [0] => 2349
            [1] => Thời điểm chính của cuộc đời bạn
            [2] => Daft Punk
            [3] => Con người sau tất cả
            [4] => 3
            [5] => 2

        )
    [1] => Danh sách
        (

Vì vậy, mlist [0] [0] sẽ nhận được TrackID từ bài hát 1, mlist [1] [0] từ bài hát 2, v.v.

Nhưng tôi đang gặp vấn đề lớn khi tạo danh sách đa chiều. Cho đến nay tôi đã nghĩ ra

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

Nhưng tôi thực sự không có nhiều tiến bộ hơn :(

Câu trả lời:


138

Vâng, bạn chắc chắn có thể sử dụng một List<List<string>>nơi bạn sau đó viết:

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

Nhưng tại sao bạn lại làm điều đó thay vì xây dựng lớp của riêng mình để đại diện cho một bản nhạc, với các thuộc tính ID bản nhạc, Tên, Nghệ sĩ, Album, Lượt phát và Lượt bỏ qua? Sau đó, chỉ cần có một List<Track>.


1
Hmm, tôi thành thật không biết làm thế nào để làm điều đó! Tôi đã xem xét việc thiết lập một lớp để xử lý danh sách phát một mình, nhưng tôi đoán đó là ý tưởng tốt hơn.
CasperT

Ngoài ra, nó sẽ không yêu cầu biết bao nhiêu bản nhạc cuối cùng tôi sẽ tạo / lưu trữ?
CasperT

2
Không, vì Danh sách <Track> vẫn có kích thước động. Bạn muốn phân tích dữ liệu cho một ca khúc, tạo một đối tượng mới của Track, thêm nó vào danh sách <Theo dõi> và sau đó phân tích kế tiếp, vv
Jon Skeet

caspert, Danh sách <T> theo dõi số lượng đối tượng mà nó lưu trữ cho bạn. Bạn có thể truy cập số tiền bằng cách gọi Danh sách <T> .Count
Spoike

3
@CasperT Vui lòng thực hiện những gì nhiều người đã đề xuất và tạo một Tracklớp học. Nó sẽ dễ dàng hơn nhiều để hiểu / duy trì mã. Nếu bạn biểu thị một bản nhạc dưới dạng danh sách các chuỗi, thì các phần nơi bạn lưu trữ một thuộc tính cụ thể sẽ phải được đồng bộ hóa trên tất cả các trường hợp mà bạn cố gắng truy cập thông tin bản nhạc. Nó sẽ trở nên tẻ nhạt để thực hiện mỗi lần và không thể gỡ lỗi. Làm ơn, vì lợi ích của riêng bạn, hãy xem xét các lớp học. :)
Alexander Kondratskiy

103

Như Jon Skeet đã đề cập, bạn có thể làm điều đó với một List<Track>thay thế. Lớp Track sẽ trông giống như sau:

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

Và để tạo một danh sách theo dõi List<Track>bạn chỉ cần làm như sau:

var trackList = new List<Track>();

Thêm bản nhạc có thể đơn giản như sau:

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

Việc truy cập các tuyến đường có thể được thực hiện với toán tử lập chỉ mục:

Track firstTrack = trackList[0];

Hi vọng điêu nay co ich.


4
Nếu bạn muốn thực sự hiểu biết, Track cũng có thể là một cấu trúc. ;)
Spoike

3
Không đúng với định nghĩa bạn đã đưa ra ... Các cấu trúc phải có kích thước phiên bản nhỏ hơn 16byte ...
Ian

@Ian: Hừ. Tôi đã không nhận thức được điều đó. Đã nhanh chóng kiểm tra tài liệu MSDN cho điều đó và hóa ra cấu trúc cần nhỏ hơn 16 byte. Cảm ơn đã chỉ ra điều đó.
Spoike

14
Họ không cần phải như vậy, đó chỉ là một đề xuất. Nó không thực sự quan trọng nhiều như vậy; chọn struct nếu bạn cần ngữ nghĩa giá trị, nếu không thì chỉ cần class. Nếu bạn không biết, hãy sử dụng một lớp học.
jason

@Spoike: cách sử dụng danh sách bên trong 2 vòng lặp for nếu bạn muốn thêm dữ liệu có trong một hàng nào đó trong khi lặp qua vòng lặp. Ví dụ: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

Đây là cách dễ nhất mà tôi đã tìm thấy để làm điều đó.

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

Để lấy các giá trị thậm chí còn dễ dàng hơn

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

4
Mặc dù gợi ý trước đó về lớp Track là tốt nhất đối với yêu cầu của OP, nhưng giải pháp NÀY là giải pháp tốt nhất để tôi xây dựng lưới hai chiều của các đối tượng. Cảm ơn!
CigarDoug

2
Vâng, đây là những gì tôi đã tìm thấy là giải pháp đơn giản và thanh lịch nhất, rất vui vì tôi đã giúp!
Jordan LaPrise

1
Đơn giản và hữu ích! Cảm ơn bạn!
Dov Miller

12

một tác phẩm khác mà tôi đã sử dụng là ...

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

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

Thư viện mà tôi đang làm việc có cấu trúc lớp rất chính thức và tôi không có thêm thứ gì vào đó một cách hiệu quả để có đặc quyền ghi lại hai int 'liên quan'.

Dựa vào việc lập trình viên chỉ nhập một mảng 2 mục nhưng vì nó không phải là một mục phổ biến nên tôi nghĩ nó hoạt động.


2

Bạn cũng có thể..thực hiện theo cách này,

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

nếu bạn cần một mục khác (con), hãy tạo một phiên bản con mới,

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

2

Đây là cách tạo danh sách 2 chiều

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

Nhận thức được sự nguy hiểm khi truy cập một vị trí không có dân cư.


1

Tôi đã sử dụng:

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

điều đó bằng:

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

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

Điều này rất hữu ích cho tôi! Cảm ơn bạn!
Dov Miller

0

Bạn cũng có thể sử dụng DataTable - sau đó bạn có thể xác định số lượng cột và loại của chúng, sau đó thêm hàng http://www.dotnetperls.com/datatable


Thanh tốt hơn để các List<Track>cách tiếp cận và sử dụng một BindingSource, bằng cách thêm một DataSource để bạn DataGridViewloại Trackđể hỗ trợ các lớp học mạnh mẽ gõ trong mã và dễ dàng để cấu hình trực quan của các ca khúc trong xem lưới dữ liệu.
Oliver

Đồng ý, nhưng đôi khi bạn không muốn hiển thị dữ liệu ngay lập tức và bạn không muốn tạo thêm một lớp chỉ để sử dụng nó ở một nơi duy nhất nên tôi thích sử dụng giải pháp hiện có hơn. ... Chỉ muốn chỉ ra một cách nữa để giải quyết vấn đề này! ;)
Val

0

Đây là một vài thứ mà tôi đã làm cách đây một thời gian cho một công cụ trò chơi mà tôi đang làm việc. Nó được sử dụng như một người giữ biến đối tượng cục bộ. Về cơ bản, bạn sử dụng nó như một danh sách bình thường, nhưng nó giữ giá trị ở vị trí của tên chuỗi (hoặc ID). Một chút sửa đổi và bạn sẽ có danh sách 2D của mình.

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);
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.