Как я преобразовываю от Словаря до SortedDictionary с помощью LINQ в C#?

На самом деле в документации для $type есть «gotcha», в частности, о массивах:

При применении к массивам тип $ соответствует любому внутреннему элементу то есть указанного типа. Без проекции это означает, что весь массив будет соответствовать, если какой-либо элемент имеет правильный тип. С проекцией результаты будут включать только те элементы запрашиваемого типа.

blockquote>

Таким образом, это означает, что вместо того, чтобы определять, находится ли сам элемент в массиве, то, что на самом деле тестируется, является «внутренний элемент» массива, чтобы увидеть, какой он тип.

Теперь сама документация предлагает этот тест JavaScript с помощью $where :

.find({ "$where": "return Array.isArray(this.author)" })

Но я думаю, что это довольно ужасно, поскольку есть лучший способ.

Трюк находится в «точечной нотации» , где вы запрашиваете индексный элемент 0 массива к $exists

.find({ "author.0": { "$exists": true } })

Это всего лишь основной случай, если элемент «0» существует, тогда поле присутствует, и поэтому данные являются массивом.

Как только вы понимаете эту логическую предпосылку, это довольно простой тест. Единственное, что не может сравниться с этим, это «действительно пустой» массив, и в этом случае вы можете вернуться к альтернативе JavaScript, если это необходимо. Но это может фактически использовать индекс, поэтому было бы предпочтительно использовать последнюю форму.

28
задан Guy 16 January 2009 в 20:04
поделиться

5 ответов

редактирование этот ответ был перед редактированием; для ответа на обновленную проблему см. этот ответ .

, Почему использование LINQ? Существует конструктор для этого:

new SortedDictionary<int, string>(existing);

Вы могли добавлять ToSortedDictionary - но я не обеспокоился бы...

48
ответ дан Community 14 October 2019 в 10:31
поделиться

Никакой LINQ не необходим. SortedDictionary имеет конструктора, чтобы сделать преобразование.

public SortedDictionary<TKey,TValue> Convert<TKey,TValue>(Dictionary<TKey,TValue> map) {
  return new SortedDictionary<TKey,TValue>(map);
}
8
ответ дан JaredPar 14 October 2019 в 10:31
поделиться

Вам не нужен LINQ, просто некоторые изящные дополнительные методы:

public static IDictionary<TKey, TValue> Sort<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
    if(dictionary == null)
    {
        throw new ArgumentNullException("dictionary");
    }

    return new SortedDictionary<TKey, TValue>(dictionary);
}

public static IDictionary<TKey, TValue> Sort<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
{
    if(dictionary == null)
    {
        throw new ArgumentNullException("dictionary");
    }

    if(comparer == null)
    {
        throw new ArgumentNullException("comparer");
    }

    return new SortedDictionary<TKey, TValue>(dictionary, comparer);
}

использование В качестве примера:

var dictionary = new Dictionary<int, string>
{
    { 1, "one" },
    { 2, "two" },
    { 0, "zero" }
};

foreach(var pair in dictionary.Sort())
{
    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

// 0: zero
// 1: one
// 2: two
1
ответ дан Bryan Watts 14 October 2019 в 10:31
поделиться

Инверсия с помощью ToDictionary:

public static IDictionary<TValue, TKey> Invert<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
    if(dictionary == null)
    {
        throw new ArgumentNullException("dictionary");
    }

    return dictionary.ToDictionary(pair => pair.Value, pair => pair.Key);
}

использование В качестве примера:

var dictionary = new Dictionary<string, int>
{
    { "zero", 0 },
    { "one", 1 },
    { "two", 2 }
};

foreach(var pair in dictionary.Invert())
{
    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

// 0: zero
// 1: one
// 2: two

Пример инвертирования и сортировки (см. мой другой ответ для определения Sort):

var dictionary = new Dictionary<string, int>
{
    { "one", 1 },
    { "two", 2 },
    { "zero", 0 }
};

foreach(var pair in dictionary.Invert().Sort())
{
    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

// 0: zero
// 1: one
// 2: two
0
ответ дан Bryan Watts 14 October 2019 в 10:31
поделиться

Кажется, как будто Вы просите изящный способ взять Dictionary<TKey,TValue> и превратить, это в SortedDictionary<TValue,TKey> (обратите внимание, что значение эти Dictionary является теперь ключом SortedDictionary). Я не вижу, что любой ответ обращается к этому, таким образом, здесь он идет.

Вы могли создать дополнительный метод, который похож на это:

static class Extensions
{
    public static Dictionary<TValue, TKey> 
         AsInverted<TKey, TValue>(this Dictionary<TKey, TValue> source)
    {
        var inverted = new Dictionary<TValue, TKey>();

        foreach (KeyValuePair<TKey, TValue> key in source)
            inverted.Add(key.Value, key.Key);

        return inverted;
    }
}

И Ваш код приложения был бы похож на это:

using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var dict = new Dictionary<String, Double>();
        dict.Add("four", 4);
        dict.Add("three", 3);
        dict.Add("two", 2);
        dict.Add("five", 5);
        dict.Add("one", 1);

        var sortedDict = new SortedDictionary<Double, String>(dict.AsInverted());
    }
}
5
ответ дан Andrew Hare 14 October 2019 в 10:31
поделиться
Другие вопросы по тегам:

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