Сортировка документов в firebase firebase выполняется firebase. Если вы хотите получить документ на основе времени создания, вам нужно создать поле, скажем, время и сохранить serverTimestamp. Теперь при запросе документа вы можете использовать предложение orderBy, чтобы получить документ.
Чтобы добавить документ:
this.afs.collection('values').add({
time:firebase.firestore.FieldValue.serverTimestamp()
});
. Чтобы получить документ:
this.afs.collection('values',ref=>ref.OrderBy('time','desc')).valueChanges();
, это даст вам заметку о документах. По подписке вы получите массив документов, где первый элемент массива является последним добавленным документом
OrderBy
расширение LINQ, которое производит новую последовательность. Для упорядочивания существующей последовательности, необходимо добавить дополнительный метод, или два... затем можно использовать:
PersonList.Sort(p => p.Attributes.Find(
s => s.Name == mySortAttribute).Value);
public static class ListExtensions {
public static void Sort<TSource, TValue>(
this List<TSource> source,
Func<TSource, TValue> selector)
{
var comparer = Comparer<TValue>.Default;
source.Sort((x, y) => comparer.Compare(selector(x), selector(y)));
}
public static void SortDescending<TSource, TValue>(
this List<TSource> source,
Func<TSource, TValue> selector)
{
var comparer = Comparer<TValue>.Default;
source.Sort((x, y) => comparer.Compare(selector(y), selector(x)));
}
}
Почему Вы не используете словарь значения ключа вместо своего Списка <PersonAttribute>? Это подошло бы лучше, я думаю и делаю все остальное легче.
Обновление - как это:
public class Person
{
public Dictionary<string, string> Attributes = new Dictionary<string,string>();
}
List<Person> people = new List<Person>();
Person rebecca = new Person();
rebecca.Attributes["Age"] = "32";
rebecca.Attributes["FirstName"] = "Rebecca";
rebecca.Attributes["LastName"] = "Johnson";
rebecca.Attributes["Gender"] = "Female";
people.Add(rebecca);
var PeopleInAgeOrder = people.OrderBy(p => p.Attributes["Age"]);
Это предполагает, что класс Атрибута реализует IComparable, или сделал, чтобы хороший ToString функционировал (я надеюсь).
var list = personList.OrderBy(p => p.Attributes.FirstOrDefault(a => a.Name == "Age"))
Иначе синтаксис становится более замысловатым:
var list = personList
.OrderBy(p =>
p.Attributes.FirstOrDefault(a => a.Name == "Age") == null ?
"" : p.Attributes.First(a => a.Name == "Age").Value
);
Я также предполагаю, что у Вас есть одно значение для каждого ключа - иначе у Вас должен был бы быть более умный код... ;-)
Могло случиться так, что Ваш синтаксис является неправильным? Ваше свойство называют Атрибутами, но Вашим использованием чего-то названного ObjectSettings в коде? Или то, что опечатка.
Если это - затем Ваш код, выглядит хорошо, если не все экземпляры Человека не имеют Атрибут, Вы пытаетесь заказать, в этом случае, Вы получили бы исключение.
Править: Кроме того, вместо использования Находят, пытаются использовать Сначала.
PersonList.OrderBy(p => p.Attributes.First(a => a.Name == "Age").Value)
Я предположил бы, что Вы получаете исключение, где один объект не имеет атрибута возраста. Я попробовал ниже кода, и он хорошо работал - я предполагаю, что Ваши данные немного выключены, как указано другими плакатами. Так или иначе, ниже хорошо работает...
List<Person> personList = new List<Person>();
Random rand = new Random();
//generate 50 random persons
for (int i = 0; i < 50; i++)
{
Person p = new Person();
p.Attributes = new List<PersonAttribute>();
p.Attributes.Add(new PersonAttribute() { ID = 8, Name = "Age", Value = rand.Next(0, 100).ToString() });
p.Attributes.Add(new PersonAttribute() { ID = 10, Name = "Name", Value = rand.Next(0, 100).ToString() });
personList.Add(p);
}
var finalList = personList.OrderBy(c => c.Attributes.Find(a => a.Name == "Age").Value).ToList();
Я знаю, что это старый пост, но я подумал, что выложу сравнитель, который я нашел некоторое время назад, на случай, если он понадобится кому-то еще.
public class GenericComparer<T> : IComparer<T>
{
public string SortExpression { get; set; }
public int SortDirection { get; set; } // 0:Ascending, 1:Descending
public GenericComparer(string sortExpression, int sortDirection)
{
this.SortExpression = sortExpression;
this.SortDirection = sortDirection;
}
public GenericComparer() { }
#region IComparer<T> Members
public int Compare(T x, T y)
{
PropertyInfo propertyInfo = typeof(T).GetProperty(SortExpression);
IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null);
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);
if (SortDirection == 0)
{
return obj1.CompareTo(obj2);
}
else return obj2.CompareTo(obj1);
}
#endregion
}
Использование
List<MyObject> objectList = GetObjects(); /* from your repository or whatever */
objectList.Sort(new GenericComparer<MyObject>("ObjectPropertyName", (int)SortDirection.Descending));
dropdown.DataSource = objectList;
dropdown.DataBind();
Вы можете перегрузить конструктор, чтобы он принял перечисление SortDirection. Я этого не делал, потому что класс находится в библиотеке без ссылки на System.Web.
Некоторые случаи, которые необходимо учитывать:
Если вы создаете этот класс методов расширения:
public static class ListExtenstions
{
public static List<Person> OrderList(this List<Person> list, string attributeName, PersonAttribute defaultAttribute)
{
return OrderList(list, attributeName, defaultAttribute, x => x);
}
public static List<Person> OrderList<T>(this List<Person> list, string attributeName, PersonAttribute defaultAttribute, Func<string, T> convertion)
{
return list.OrderBy(x => convertion((x.Attributes.FirstOrDefault(y => y.Name == attributeName) ?? defaultAttribute).Value)).ToList();
// Query Syntax
//return
// (from p in list
// let attribute = p.Attributes.FirstOrDefault(a => a.Name == attributeName) ?? defaultAttribute
// orderby attribute.Value
// select p).ToList();
}
}
Затем вы можете правильно отсортировать список следующим образом:
List<Person> persons = ...
...
PersonAttribute defaultAttribute = new PersonAttribute() { Value = "0" };
var ordered = persons.OrderList("Age", defaultAttribute, x => Convert.ToInt32(x));
Это даст правильный порядок сортировки. {{1 }} Если атрибут будет присутствовать всегда, вы можете удалить defaultAttribute
.
Чтобы отсортировать "Имя", просто введите:
List<Person> persons = ...
...
PersonAttribute defaultAttribute = new PersonAttribute() { Value = String.Empty };
var ordered persons.OrderList("Name", defaultAttribute);