2009-03-20 32 views
73

Tôi muốn thiết lập danh sách đa chiều. Để tham khảo, tôi đang làm việc trên một bộ phân tích danh sách phát.Danh sách 2 chiều có thể có trong C# không?

Tôi có một tệp/danh sách tệp mà chương trình của tôi lưu trong 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 bằng cụm từ thông dụng để 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 một danh sách đa chiều mới; vì tôi không biết có bao nhiêu kết quả/dữ liệu tôi sẽ kết thúc, tôi không thể sử dụng mảng đa chiều.

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

 
List 
(
    [0] => List 
     (
      [0] => Track ID 
      [1] => Name 
      [2] => Artist 
      [3] => Album 
      [4] => Play Count 
      [5] => Skip Count 

     ) 
    [1] => List 
     (
And so on.... 

Bất Ví dụ:

 
List 
(
    [0] => List 
     (
      [0] => 2349 
      [1] => The Prime Time of Your Life 
      [2] => Daft Punk 
      [3] => Human After All 
      [4] => 3 
      [5] => 2 

     ) 
    [1] => List 
     (

Vì vậy, yeah, 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 đã đưa ra

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

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

Trả lời

113

Vâng, bạn chắc chắn có thể sử dụng một List<List<string>> nơi sau đó bạn muốn 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 sẽ làm điều đó thay vì xây dựng lớp học của riêng bạn để đại diện cho một bản nhạc, với các thuộc tính Bản nhạc ID, Tên, Nghệ sĩ, Album, Lượt chơi và Số lượng bỏ qua thì chỉ cần có List<Track> .

+1

Hmm, tôi thực sự không chắc chắn cách thực hiện đ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à một ý tưởng hay hơn. – CasperT

+0

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

+2

Không, vì Danh sách vẫn có kích thước động. Bạn sẽ phân tích cú pháp dữ liệu cho một bản nhạc, tạo một bản sao mới của Bản nhạc, thêm nó vào Danh sách rồi phân tích cú pháp tiếp theo, v.v. –

89

Jon Skeet được đề cập, bạn có thể thực hiện việc này với số List<Track> thay thế. Lớp theo dõi sẽ giống như thế này:

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 ra một danh sách theo dõi như một List<Track> bạn chỉ cần làm điều này:

var trackList = new List<Track>(); 

track Thêm có thể đơn giản như thế này:

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 tuyến đường có thể được thực hiện với toán tử lập chỉ mục:

Track firstTrack = trackList[0]; 

Hy vọng điều này sẽ hữu ích.

+4

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

+3

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

+1

Cảm ơn bạn đã trình diễn! – CasperT

11

khác làm việc xung quanh mà tôi đã sử dụng là ...

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

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

Thư viện tôi đang làm việc trên có cấu trúc lớp rất trang trọng và tôi đã không wan't công cụ bổ sung trong đó có hiệu quả cho đặc quyền ghi hai int 'liên quan'.

Dựa vào 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, tôi nghĩ nó hoạt động.

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

rằng bằng:

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

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

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

0

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

+0

Tiếp cận tốt hơn cách tiếp cận 'Danh sách ' và sử dụng 'BindingSource', chỉ cần thêm một DataSource vào' DataGridView' của loại 'Track' để hỗ trợ các lớp được nhập mạnh mẽ trong mã và dễ định cấu hình trực quan các bản nhạc trong chế độ xem lưới dữ liệu. – Oliver

+0

Đồ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 nữa chỉ để sử dụng nó ở một nơi duy nhất để tôi thích sử dụng giải pháp hiện có. ... Chỉ muốn chỉ ra một cách nữa để giải quyết vấn đề này! ;) – Val

28

Đây là cách dễ nhất 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 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 
+3

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

+1

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, vui vì tôi đã giúp! –

+1

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

0

Dưới đây là làm thế nào để tạo ra một danh sách 2 chiều

// Tạo danh sách trong một vòng lặp. Danh sách> biglist = new List>();

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

Hãy nhận biết nguy cơ truy cập vào vị trí không có dân cư.

2

Bạn có thể also..do 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 (trẻ em), tạo một đối tượng mới của con,

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

Dưới đây là một chút gì đó mà Tôi đã thực hiện một lúc trước 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 biến chủ đố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 những gì bao giờ tên chuỗi là (hoặc ID). Một chút sửa đổi, và bạn sẽ có danh sách 2D của bạn.

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); 
     } 
    } 
} 
Các vấn đề liên quan