使用哪个c#集合来代替列表<;KeyValuePair<;字符串,双>>;?

使用哪个c#集合来代替列表<;KeyValuePair<;字符串,双>>;?,c#,data-structures,collections,C#,Data Structures,Collections,我想存储数据,例如 { {"apple",15 } {"pear",12.5 } {"", 10 } {"", 0.45 } } 数据将绘制在条形图上(字符串为图例,双精度为值) 插入顺序很重要。 性能没关系。 字符串可以重复或为空。(值也可以重复) 我需要得到最小值和最大值(如果可能的话很容易)来设置比例 我用 如果不是,如何不费吹灰之力地获得列表的最大值 NameValueCo

我想存储数据,例如

{
 {"apple",15   }
 {"pear",12.5  }
 {"", 10       }
 {"", 0.45     }
}
数据将绘制在条形图上(字符串为图例,双精度为值) 插入顺序很重要。 性能没关系。 字符串可以重复或为空。(值也可以重复)

我需要得到最小值和最大值(如果可能的话很容易)来设置比例

我用

如果不是,如何不费吹灰之力地获得
列表的最大值

NameValueCollection看起来不错,但它是一个
我需要一个

你看过吗

唯一的问题是它是不可变的,所以您需要能够一次性创建集合


正如安东尼·佩格拉姆(Anthony Pegram)所指出的,创建一个这样的系统有点痛苦。这取决于你的数据来自哪里。看看这个方法。

您可以创建一个如下所示的类:

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
}
然后使用LINQ和选择器获取最大值和最小值:

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

如果它的可用性值得(即,您在任何地方都使用了笨拙的
List
集合,那么实现
StringDoubleCollection
可能就值得了。用您在示例中描述的更友好的语法包装基础集合并不难

而且,正如其他评论/答案所暗示的那样,该框架似乎没有提供一个更简单的解决方案来满足您的所有需求

至于“最大值”,我假设您指的是具有最大值的键值对。它可以这样检索:

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

只需定义您自己的模型类来保存数据,而不是依赖于KeyValuePair,一切都会变得更干净:

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...
    }
}
使用系统;
使用System.Collections.Generic;
公共级水果
{
公共字符串名称{get;set;}
公共双价{get;set;}
}
公共课程
{
公共静态void Main()
{
列表_myFruit=新列表();
_添加(新水果{Name=“apple”,价格=15});
_添加(新水果{Name=“pear”,价格=12.5});
_添加(新水果{Name=”“,价格=10});
_添加(新水果{Name=”“,价格=0.45});
//等等。。。
}
}

如何实现StringDoubleCollection,使其按您想要的方式工作

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));
    }
}
公共类集合
{
私有列表值;
公共列表值
{
获取{return myValues.Select(keyValuePair=>keyValuePair.Value).ToList();}
}
公共void add(字符串键,双值)
{
添加(新的KeyValuePair(key,value));
}
}

要确定您真正想要的数据结构,让我们看看您的使用模式

  • 插入订单事项
  • 您不能通过密钥访问您的项目
  • 你想要最小值和最大值
堆提供最小值或最大值,但不保留顺序。基于哈希的字典也不保留顺序。列表实际上是数据结构的良好选择。它是可用的,并且提供了极好的支持

您可以通过为数据结构和条形数据定义类来美化代码。您还可以向集合添加最小/最大功能。注意:我没有使用Linq最小/最大函数,因为它们返回最小值,而不是最小元素

公共类条形图数据{
公共字符串图例{get;set;}
公共双值{get;set;}
}
公共类BarGraphDataCollection:列表{
//添加必要的构造函数(如果有)
公共数据最小值(){
BarGraphData最小值=空;
//查找最小项
//首选索引最低的项目
foreach(本文件中的Bargraph数据项){
if(min==null)
最小值=项目;
否则如果(项目值<最小值)
最小值=项目;
}
if(min==null)
抛出新的InvalidOperationException(“列表为空”);
返回最小值;
}
公共数据最大值(){
//与Min类似的实现
}
}

stackoverflow因为没有逃过某些“为您修复格式设置”而扼杀了我的帖子。您需要的基本上是一个允许重复键的字典。根据这个问题:框架中没有支持它的内容。您可能需要创建自己的NameValueCollection通用版本。谢谢Ray解决这个问题这是因为它不是直接实例化的。你可以从其他东西开始,然后投射到这个。他首先需要一个中间结构。是的,这是真的。但这可能仍然是可能的,取决于他的数据来自哪里(没有提供任何信息)。无论如何,这是值得了解的。很抱歉,我在阅读时跳过了重复部分。无论如何,编辑:)最好删除字典中的部分,而不是让编辑解释它。封装类是一个很有价值的建议,所以我对答案投了赞成票。
// Inside X class...
public static implicit operator X(double d)
{
    return new X(d);
}

// Somewhere else...
data.Add(50.0);
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...
    }
}
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));
    }
}
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
    }
}