2011-09-21 25 views
6

Tôi muốn để lưu trữ dữ liệu nhưbộ sưu tập nào C# để sử dụng thay cho Danh sách <KeyValuePair <string, double >>?

{ 
{"apple",15 } 
{"pear",12.5 } 
{"", 10  } 
{"", 0.45  } 
} 

Dữ liệu sẽ được vẽ trên một biểu đồ thanh (string sẽ là huyền thoại và đôi sẽ là giá trị) Chèn trật tự là rất quan trọng. Perfs không quan trọng. Chuỗi có thể bị nhân đôi hoặc trống. (giá trị có thể được sao chép quá)

Tôi cần nhận giá trị tối thiểu và tối đa (dễ dàng nếu có thể) để đặt tỷ lệ.

tôi sử dụng

List<KeyValuePair<string, double>> data = new List<KeyValuePair<string, double>>(); 
data.Add(new KeyValuePair<string,double>("",i)); 

Khá nhàm chán và không thể đọc được. Có cách nào sạch hơn không?

StringDoubleCollection data = new StringDoubleCollection(); 
data.add("apple",15); 
data.add("",10); 

double max = data.values.Max(); 
double min = data.values.Min(); 

nếu không làm thế nào để có được giá trị tối đa của List<KeyValuePair<string, double>> mà không cần quá nhiều rắc rối

NameValueCollection trông đẹp, nhưng nó là một <string,string> Tôi cần một <string,double>

cảm ơn bạn

+0

stackoverflow đã giết bài đăng của tôi bằng cách không thoát một số '<'. Vì vậy, nhận xét cuối cùng của tôi là làm thế nào để có được giá trị tối đa của List > và NameValueCollection là tốt đẹp nhưng một tôi cần một frenchone

+0

sửa định dạng cho bạn. – Ray

+0

Điều bạn muốn về cơ bản là từ điển cho phép các phím trùng lặp. Theo câu hỏi này: http://stackoverflow.com/questions/146204/duplicate-keys-in-net-dictionaries không có gì trong Framework hỗ trợ nó. Có thể bạn sẽ cần tạo phiên bản chung của NameValueCollection. –

Trả lời

1

Để xác định cấu trúc dữ liệu bạn thực sự muốn, hãy xem xét các mẫu sử dụng của bạn.

  • Chèn thứ tự quan trọng.
  • Bạn không truy cập các mục của mình theo khóa.
  • Bạn muốn tối thiểu và tối đa.

Một đống cung cấp tối thiểu hoặc tối đa, nhưng không giữ được thứ tự. Một từ điển dựa trên băm cũng không bảo vệ trật tự. Danh sách thực sự là một lựa chọn tốt cho cấu trúc dữ liệu của bạn. Nó có sẵn và cung cấp hỗ trợ tuyệt vời.

Bạn có thể xác định mã của mình bằng cách xác định các lớp cho cả cấu trúc dữ liệu và dữ liệu thanh của bạn. Và bạn có thể thêm chức năng tối thiểu/tối đa vào bộ sưu tập. Lưu ý: Tôi đã không sử dụng các hàm LINQ Min/Max, vì chúng trả về giá trị tối thiểu , không phải là yếu tố tối thiểu .

public class BarGraphData { 
    public string Legend { get; set; } 
    public double Value { get; set; } 
} 

public class BarGraphDataCollection : List<BarGraphData> { 
    // add necessary constructors, if any 

    public BarGraphData Min() { 
     BarGraphData min = null; 
     // finds the minmum item 
     // prefers the item with the lowest index 
     foreach (BarGraphData item in this) { 
      if (min == null) 
       min = item; 
      else if (item.Value < min.Value) 
       min = item; 
     } 
     if (min == null) 
      throw new InvalidOperationException("The list is empty."); 
     return min; 
    } 

    public BarGraphData Max() { 
     // similar implementation as Min 
    } 
} 
1

Bạn đã nhìn LookUp?

Vấn đề duy nhất là nó không thay đổi, vì vậy bạn cần có thể tạo bộ sưu tập của mình chỉ trong một lần.

Như Anthony Pegram lưu ý, đó là một chút đau đớn khi tạo ra. Nó phụ thuộc vào nơi dữ liệu của bạn đến từ đâu. Hãy xem phương thức ToLookup.

+1

Vấn đề với điều này là nó không thể trực tiếp tức thời. Bạn bắt đầu từ một cái gì đó khác và sau đó có thể dự án này. Anh ta cần một cấu trúc trung gian trước. –

+0

Đúng vậy. Nhưng nó vẫn có thể tùy thuộc vào nơi dữ liệu của ông đến từ đâu (không có thông tin nào được cung cấp). Đó là giá trị biết về trong mọi trường hợp. – Ray

5

Bạn có thể tạo ra một lớp như sau:

class X 
{ 
    public string Name { get; set; } 
    public double Value { get; set; } 

    // name is an optional parameter (this means it can be used only in C# 4) 
    public X(double value, string name = "") 
    { 
     this.Name = name; 
     this.Value = value; 
    } 

    // whatever 
} 

Và sau đó nhận được giá trị tối đa và tối thiểu sử dụng LINQ với một selector:

var data = new List<X>(); 
data.Add(new X(35.0, "Apple")) 
data.Add(new X(50.0)); 

double max = data.Max(a => a.Value); 
double min = data.Min(a => a.Value); 

EDIT: nếu mã ở trên dường như vẫn còn không thể đọc được để bạn cố gắng cải thiện nó bằng cách sử dụng toán tử cho các trường hợp mà bạn muốn chỉ có giá trị.

// Inside X class... 
public static implicit operator X(double d) 
{ 
    return new X(d); 
} 

// Somewhere else... 
data.Add(50.0); 
+0

Và "Thứ tự chèn là quan trọng." ... –

+0

Tôi xin lỗi, tôi đã bỏ qua phần * trùng lặp * khi đọc. Vẫn được chỉnh sửa :) –

+0

Sẽ là một ý tưởng hay khi chỉ cần loại bỏ một chút về từ điển thay vì để chỉnh sửa của bạn giải thích nó đi. Một lớp đóng gói là một gợi ý xứng đáng, vì vậy tôi đã bình chọn câu trả lời. –

1

Nếu nó có giá trị nó cho khả năng sử dụng (ví dụ bạn đang sử dụng bộ sưu tập vụng về của List<KeyValuePair<string, double>> ở khắp mọi nơi, nó chỉ có thể là giá trị nó để thực hiện StringDoubleCollection. Nó sẽ không thể là khó khăn để bọc các bộ sưu tập cơ bản với các thân thiện hơn cú pháp bạn đã mô tả trong ví dụ của bạn.

Và, như ý kiến ​​khác/câu trả lời được cho thấy, khung dường như không cung cấp một giải pháp đơn giản phù hợp với tất cả các yêu cầu của bạn ...

đối với " giá trị tối đa ", tôi giả sử bạn có nghĩa là Cặp khóa-giá trị có giá trị lớn nhất.Nó có thể được lấy ra như vậy:

var max = list.Select(kvp => kvp.Value).Max(); 
0

Chỉ cần xác định mô hình lớp học của riêng bạn để giữ dữ liệu thay vì phụ thuộc vào một KeyValuePair và mọi thứ trở nên sạch hơn:

using System; 
using System.Collections.Generic; 

public class Fruit 
{ 
    public string Name {get; set;} 
    public double Price {get; set;} 
} 

public class Program 
{ 
    public static void Main() 
    { 
     List<Fruit> _myFruit = new List<Fruit>(); 

     _myFruit.Add(new Fruit{Name="apple", Price=15 }); 
     _myFruit.Add(new Fruit{Name="pear", Price=12.5 }); 
     _myFruit.Add(new Fruit{Name="", Price=10  }); 
     _myFruit.Add(new Fruit{Name="", Price=0.45  }); 

     // etc... 
    } 
} 
0

gì về việc thực hiện các StringDoubleCollection để làm việc như bạn muốn ...

public class StringDoubleCollection 
{ 
    private List<KeyValuePair<string, double>> myValues; 
    public List<double> values 
    { 
     get { return myValues.Select(keyValuePair => keyValuePair.Value).ToList(); } 
    } 

    public void add(string key, double value) 
    { 
     myValues.Add(new KeyValuePair<string,double>(key,value)); 
    } 
} 
Các vấn đề liên quan