какую коллекцию c # использовать вместо List <KeyValuePair <string, double >>? - PullRequest
6 голосов
/ 21 сентября 2011

Я хочу сохранить такие данные, как

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

Данные будут нанесены на гистограмму (строка будет легендой, а double будет значением) Порядок вставки важен.Perfs не имеет значения. Строки могут дублироваться или быть пустыми. (значения также могут дублироваться)

Мне нужно получить минимальное и максимальное значения (легко, если возможно), чтобы установить масштаб.

Я пользуюсь

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<KeyValuePair<string, double>> без особых хлопот

NameValueCollection выглядит красиво, но это <string,string> Iнужно <string,double>

спасибо

Ответы [ 6 ]

5 голосов
/ 21 сентября 2011

Вы можете создать класс, подобный следующему:

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);
1 голос
/ 21 сентября 2011

Чтобы определить, какую структуру данных вы действительно хотите, давайте рассмотрим ваши схемы использования.

  • Порядок ввода имеет значение.
  • Вы не можете получить доступ к своим товарам по ключу.
  • Вы хотите мин и макс.

Куча предлагает мин или макс, но не сохраняет порядок. Словарь на основе хеша также не сохраняет порядок. Список на самом деле является хорошим выбором для вашей структуры данных. Он доступен и предлагает отличную поддержку.

Вы можете предварительно оптимизировать свой код, определив классы как для структуры данных, так и для данных панели. И вы можете добавить минимальную / максимальную функциональность в коллекцию. Примечание: я не использовал функции 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
    }
}
1 голос
/ 21 сентября 2011

Просто определите свой собственный класс модели для хранения данных вместо зависимости от 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...
    }
}
1 голос
/ 21 сентября 2011

Если оно того стоит для удобства использования (т. Е. Вы используете неуклюжие коллекции List<KeyValuePair<string, double>> везде, возможно, стоит реализовать StringDoubleCollection. Было бы не так сложно обернуть базовую коллекцию более дружественнойсинтаксис, который вы описали в своем примере.

И, как предлагают другие комментарии / ответы, Framework, кажется, не предоставляет более простого решения, которое соответствует всем вашим требованиям ...

Что касается «максимального значения», то я предполагаю, что вы имеете в виду пару ключ-значение с наибольшим значением, которую можно получить так:

var max = list.Select(kvp => kvp.Value).Max();
1 голос
/ 21 сентября 2011

Вы смотрели на LookUp ?

Единственная проблема заключается в том, что она неизменна, поэтому вам нужно иметь возможность создавать свою коллекцию за один раз.

КакЭнтони Пеграм отмечает, что создать его - это немного больно.Это зависит от того, откуда ваши данные.Взгляните на метод ToLookup .

0 голосов
/ 21 сентября 2011

А как насчет того, чтобы реализация 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));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...