使用哪个 C# 集合代替 List>?

发布于 2024-12-05 15:51:35 字数 898 浏览 0 评论 0 原文

我想存储数据,例如

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

数据将绘制在条形图上(字符串将是图例,双精度将是值) 插入顺序很重要。 性能并不重要。 字符串可以重复或为空。(值也可以重复)

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

我使用

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

相当无聊且难以阅读。 有没有更干净的方法来做到这一点?

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

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

如果不是如何轻松获取 List> 的最大值

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

I want to store data such as

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

Data will be plotted on a bar chart (string will be the legend and double will be the value)
Insert order is important.
Perfs don't matter.
Strings could be duplicated or empty. (values could be duplicated too)

I need to get min and max values (easily if possible) to set the scale.

I use

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

Quite boring and unreadable.
Is there a cleaner way to do it ?

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

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

if not how to get the max value of List<KeyValuePair<string, double>> without too much hassle

NameValueCollection looks nice but its a <string,string> I need a <string,double>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

束缚m 2024-12-12 15:51:35

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

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

编辑: 如果上面的代码对您来说仍然不可读,请尝试使用运算符来改进它,适用于以下情况你想要的只是价值。

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

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

You could create a class like the following:

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
}

And then get maximum and minimum values using LINQ with a 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: if the code above still seems unreadable to you try to improve it using an operator for cases in which you want to have just the value.

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

// Somewhere else...
data.Add(50.0);
心房的律动 2024-12-12 15:51:35

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

  • 插入顺序很重要。
  • 您无法通过密钥访问您的物品。
  • 你想要最小值和最大值。

堆提供最小值最大值,但不保留顺序。基于哈希的字典也不保留顺序。对于您的数据结构来说,列表实际上是一个不错的选择。它可用并提供出色的支持。

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

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

To determine which data structure you really want, lets look at your usage patterns.

  • Insert order matters.
  • You don't access your items by key.
  • You want min and max.

A heap offers min or max, but doesn't preserve order. A hash based dictionary also doesn't preserve order. A List is actually a good choice for your data structure. It is available and offers excellent support.

You can prettify your code by defining classes for both the data structure and your bar data. And you can add min/max functionality to the collection. Note: I didn't use the Linq Min/Max functions, because they return the minimum value, not the minimum element.

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
    }
}
那片花海 2024-12-12 15:51:35

您是否看过LookUp

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

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

Have you looked at LookUp?

The only problem is that it's immutable, so you need to be able to create your collection in one go.

As Anthony Pegram notes, it's a bit of a pain to create one. It depends on where your data is coming from. Have a look at the ToLookup method.

单身狗的梦 2024-12-12 15:51:35

如果为了可用性而值得(即您在任何地方都使用 List> 的笨拙集合,那么实现 StringDoubleCollection 可能是值得的使用您在示例中描述的更友好的语法包装底层集合并不困难,

并且正如其他评论/答案所暗示的那样,框架似乎没有提供匹配的更简单的解决方案。您的所有要求...

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

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

If it's worth it for usability (i.e. you're using awkward collections of List<KeyValuePair<string, double>> everywhere, it might just be worth it to implement StringDoubleCollection. It wouldn't be that difficult to wrap the underlying collection with the friendlier syntax you've described in your example.

And, as other comments / answers are suggesting, the Framework doesn't seem to provide a simpler solution that matches all of your requirements...

As for "max value", I assume you mean the Key-Value Pair with the greatest value. It can be retrieved like so:

var max = list.Select(kvp => kvp.Value).Max();
允世 2024-12-12 15:51:35

只需定义您自己的模型类来保存数据,而不是依赖于 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...
    }
}

Just define your own model class to hold the data instead of depending on a KeyValuePair and everything becomes cleaner:

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...
    }
}
倚栏听风 2024-12-12 15:51:35

如何实现 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));
    }
}

What about implementing the StringDoubleCollection to work like you want...

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));
    }
}
带刺的爱情 2024-12-12 15:51:35

您可以实现 Dictionary;

   Dictionary<string, string> openWith = new Dictionary<string, string>();


   openWith.Add("txt", "notepad.exe");
   openWith.Add("bmp", "paint.exe");
   openWith.Add("dib", "paint.exe");
   openWith.Add("rtf", "wordpad.exe");

https:// learn.microsoft.com/pt-br/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0

You can implementing Dictionary<key, value>

   Dictionary<string, string> openWith = new Dictionary<string, string>();


   openWith.Add("txt", "notepad.exe");
   openWith.Add("bmp", "paint.exe");
   openWith.Add("dib", "paint.exe");
   openWith.Add("rtf", "wordpad.exe");

https://learn.microsoft.com/pt-br/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文