На самом деле в документации для $type
есть «gotcha», в частности, о массивах:
При применении к массивам тип $ соответствует любому внутреннему элементу то есть указанного типа. Без проекции это означает, что весь массив будет соответствовать, если какой-либо элемент имеет правильный тип. С проекцией результаты будут включать только те элементы запрашиваемого типа.
blockquote>Таким образом, это означает, что вместо того, чтобы определять, находится ли сам элемент в массиве, то, что на самом деле тестируется, является «внутренний элемент» массива, чтобы увидеть, какой он тип.
Теперь сама документация предлагает этот тест JavaScript с помощью
$where
:.find({ "$where": "return Array.isArray(this.author)" })
Но я думаю, что это довольно ужасно, поскольку есть лучший способ.
Трюк находится в «точечной нотации» , где вы запрашиваете индексный элемент
0
массива к$exists
.find({ "author.0": { "$exists": true } })
Это всего лишь основной случай, если элемент «0» существует, тогда поле присутствует, и поэтому данные являются массивом.
Как только вы понимаете эту логическую предпосылку, это довольно простой тест. Единственное, что не может сравниться с этим, это «действительно пустой» массив, и в этом случае вы можете вернуться к альтернативе JavaScript, если это необходимо. Но это может фактически использовать индекс, поэтому было бы предпочтительно использовать последнюю форму.
редактирование этот ответ был перед редактированием; для ответа на обновленную проблему см. этот ответ .
, Почему использование LINQ? Существует конструктор для этого:
new SortedDictionary<int, string>(existing);
Вы могли добавлять ToSortedDictionary
- но я не обеспокоился бы...
Никакой LINQ не необходим. SortedDictionary имеет конструктора, чтобы сделать преобразование.
public SortedDictionary<TKey,TValue> Convert<TKey,TValue>(Dictionary<TKey,TValue> map) {
return new SortedDictionary<TKey,TValue>(map);
}
Вам не нужен 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
Инверсия с помощью 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
Кажется, как будто Вы просите изящный способ взять 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());
}
}