При использовании оператора Where LINQ на Словаре, как я могу возвратить словарь того же типа?

Вы можете построить разные столбцы одного и того же файла следующим образом:

plot 'file' using 0:1 with lines, '' using 0:2 with lines ...

(... означает продолжение). Пара примечаний к этой записи: using указывает, какой столбец будет отображаться, то есть столбцы 0 и 1 в первом операторе using, 0-й столбец - это псевдостолбец, который преобразуется в номер текущей строки в файле данных. Обратите внимание, что если с using используется только один аргумент (например, using n), это соответствует высказыванию using 0:n (спасибо, что указали на mgilson ).

Если ваша версия Gnuplot достаточно свежая, вы сможете построить все 4 столбца с циклом for:

set key outside
plot for [col=1:4] 'file' using 0:col with lines

Результат:

for-loop plot

Gnuplot может использовать заголовки столбцов для заголовка, если они находятся в файле данных, например:

min max mean std
24 31 29.0909 2.57451
12 31 27.2727 5.24129
14 31 26.1818 5.04197
22 31 27.7273 3.13603
22 31 28.1818 2.88627

и

set key outside
plot for [col=1:4] 'file' using 0:col with lines title columnheader

Результатов:

for-loop plot with column headers

7
задан M4N 27 May 2009 в 17:19
поделиться

3 ответа

Похоже, очень много суетятся о поиске вещей в Списке. Если список содержит всего несколько элементов, тогда ничего страшного. Если список содержит тысячи элементов, вам понадобится O (1) поиск в нем. HashSet может предоставить это.

Dictionary<string, string> getValidIds(
  Dictionary<string, string> SalesPersons,
  List<string> ids
)
{
  HashSet<string> idsFast = new HashSet<string>(ids);
  Dictionary<string, string> result = SalesPersons
    .Where(kvp => idsFast.Contains(kvp.Key))
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
  return result;
}
6
ответ дан 6 December 2019 в 08:17
поделиться

Интересно, что если вы сначала пронумеруете словарь (длина N) и проверите список (длина M) на предмет включения, то вы получите производительность O (NM).

Вы можете создать HashSet <> идентификаторов, но это кажется избыточным, поскольку у нас уже есть (предварительно хешированный) словарь.

Вместо этого я бы сначала перебрал идентификаторы; поскольку поиск в словаре (по ключу) равен O (1), это дает производительность O (M) - однако это может означать, что вы не используете LINQ (поскольку TryGetValue не любит LINQ (и введение кортежа слишком похоже на тяжелую работу) ...

    Dictionary<string, string> getValidIds(
            IDictionary<string, string> salesPersons,
            IEnumerable<string> ids) {
        var result = new Dictionary<string, string>();
        string value;
        foreach (string key in ids) {
            if (salesPersons.TryGetValue(key, out value)) {
                result.Add(key, value);
            }
        }
        return result;
    }

Меня не особо беспокоит, что здесь больше строк, чем в версии LINQ, это убирает O (N) сложности ...


Edit; следующий может работать (я не тестировал), но я думаю, что это злоупотребление LINQ и, конечно, не масштабируется до PLINQ и т. д. используйте с особой осторожностью !! Я также считаю, что подход foreach просто имеет меньше накладных расходов, поэтому будет быстрее ... в любом случае:

    Dictionary<string, string> getValidIds(
        IDictionary<string, string> salesPersons,
        IEnumerable<string> ids)
    {
        string value = null;
        return  (from key in ids
                where salesPersons.TryGetValue(key, out value) // HACK: v. dodgy
                select new { key, value })
                .ToDictionary(x=>x.key, x=>x.value);
    }
6
ответ дан 6 December 2019 в 08:17
поделиться

Уверен, что вы можете просто вызвать ToDictionary в результате вызова Where:

Dictionary<string, string> GetValidIds(Dictionary<string, string> salesPersons,
    IList<string> ids)
{
    return salesPersons
        .Where(p => ids.Contains(p.Key))
        .ToDictionary(p => p.Key, p => p.Value);
}
10
ответ дан 6 December 2019 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: