Я предпочитаю использовать awk
. Если есть только один столбец, используйте $0
, иначе замените его на последний столбец.
Один из способов,
awk '{print $0, "string to append after each line"}' file > new_file
или это,
awk '$0=$0"string to append after each line"' file > new_file
Самый простой способ, который я могу придумать, - использовать Linq:
List<Order> SortedList = objListOrder.OrderBy(o=>o.OrderDate).ToList();
Чтобы сделать это без LINQ на .Net2.0:
List<Order> objListOrder = GetOrderList();
objListOrder.Sort(
delegate(Order p1, Order p2)
{
return p1.OrderDate.CompareTo(p2.OrderDate);
}
);
Если вы находитесь на .Net3.0, то ответ [LQH] LukeH - это то, что вы после .
Чтобы сортировать по нескольким свойствам, вы все равно можете сделать это в пределах делегата. Например:
orderList.Sort(
delegate(Order p1, Order p2)
{
int compareDate = p1.Date.CompareTo(p2.Date);
if (compareDate == 0)
{
return p2.OrderID.CompareTo(p1.OrderID);
}
return compareDate;
}
);
Это даст вам восходящие даты с нисходящим порядком.
Тем не менее, я бы не рекомендовал прикреплять делегатов, поскольку это будет означать много мест без повторного использования кода. Вы должны реализовать IComparer
и просто передать это до вашего метода Sort
. См. здесь .
public class MyOrderingClass : IComparer<Order>
{
public int Compare(Order x, Order y)
{
int compareDate = x.Date.CompareTo(y.Date);
if (compareDate == 0)
{
return x.OrderID.CompareTo(y.OrderID);
}
return compareDate;
}
}
И затем, чтобы использовать этот класс IComparer, просто создайте его и передайте его вашему методу Сортировка:
IComparer<Order> comparer = new MyOrderingClass();
orderList.Sort(comparer);
IComparer
, предоставляя нам полиморфное поведение.
– radarbob
16 October 2014 в 15:55
Использование LINQ
objListOrder = GetOrderList()
.OrderBy(o => o.OrderDate)
.ToList();
objListOrder = GetOrderList()
.OrderBy(o => o.OrderId)
.ToList();
Вы можете сделать что-то более общее в выборе свойств, но определенно о типе, который вы выбираете, в вашем случае «Заказ»:
записывать вашу функцию как общую:
public List<Order> GetOrderList<T>(IEnumerable<Order> orders, Func<Order, T> propertySelector)
{
return (from order in orders
orderby propertySelector(order)
select order).ToList();
}
, а затем использовать его следующим образом:
var ordersOrderedByDate = GetOrderList(orders, x => x.OrderDate);
Вы можете быть еще более общим и определить открытый тип для того, что вы хотите заказать:
public List<T> OrderBy<T,P>(IEnumerable<T> collection, Func<T,P> propertySelector)
{
return (from item in collection
orderby propertySelector(item)
select item).ToList();
}
и использовать его таким же образом:
var ordersOrderedByDate = OrderBy(orders, x => x.OrderDate);
Какой глупый ненужный сложный способ сделать стиль LINQ «OrderBy», но он может дать вам представление о том, как он может быть реализован в общий способ
Ни один из вышеперечисленных ответов не был достаточно общим для меня, поэтому я сделал это:
var someUserInputStringValue = "propertyNameOfObject i.e. 'Quantity' or 'Date'";
var SortedData = DataToBeSorted
.OrderBy(m => m.GetType()
.GetProperties()
.First(n =>
n.Name == someUserInputStringValue)
.GetValue(m, null))
.ToList();
Осторожно на массивные массивы данных. Это простой код, но может вызвать у вас проблемы, если коллекция огромна, а тип объекта коллекции имеет большое количество полей. Время запуска - NxM, где:
N = # элементов в коллекции
M = # свойств в объекте
На основе Comparer GenericTypeTea: мы можем получить большую гибкость, добавив флаги сортировки:
public class MyOrderingClass : IComparer<Order> {
public int Compare(Order x, Order y) {
int compareDate = x.Date.CompareTo(y.Date);
if (compareDate == 0) {
int compareOrderId = x.OrderID.CompareTo(y.OrderID);
if (OrderIdDescending) {
compareOrderId = -compareOrderId;
}
return compareOrderId;
}
if (DateDescending) {
compareDate = -compareDate;
}
return compareDate;
}
public bool DateDescending { get; set; }
public bool OrderIdDescending { get; set; }
}
В этом сценарии вы должны создать экземпляр как MyOrderingClass явно (а не IComparer), чтобы установить его сортировку свойства:
MyOrderingClass comparer = new MyOrderingClass();
comparer.DateDescending = ...;
comparer.OrderIdDescending = ...;
orderList.Sort(comparer);
var obj = db.Items.Where...
var orderBYItemId = obj.OrderByDescending(c => Convert.ToInt32(c.ID));
Выполнение этого без Linq, как вы сказали:
public class Order : IComparable
{
public DateTime OrderDate { get; set; }
public int OrderId { get; set; }
public int CompareTo(object obj)
{
Order orderToCompare = obj as Order;
if (orderToCompare.OrderDate < OrderDate || orderToCompare.OrderId < OrderId)
{
return 1;
}
if (orderToCompare.OrderDate > OrderDate || orderToCompare.OrderId > OrderId)
{
return -1;
}
// The orders are equivalent.
return 0;
}
}
Затем просто позвоните .sort () в свой список Orders
null
на as
. В чем смысл as
, поскольку (ha, ha) (Order)obj
выдает исключение, когда он терпит неудачу. if(orderToCompare == null) return 1;
.
– radarbob
16 October 2014 в 15:30
as
возвращает null
, если сбой происходит. Но, по крайней мере, нулевой тест прав.
– radarbob
3 October 2017 в 06:03
List<Order>
, поэтому тип должен быть гарантированно соответствовать на as
, поэтому в 2014 году вы, вероятно, не писали ошибку, чтобы избежать ненужной защиты заявление :)
– Jimmy Hoffa
7 November 2017 в 17:01
List<Order>
; но вы и я оба встретили программиста с самоинкапсулированными данными, у которого невысказанная презумпция есть «я пишу этот код, чтобы он не использовался неправильно».
– radarbob
7 November 2017 в 22:31
Для использования CompareTo
требуется любой, кто работает с типами NULL, Value
.
objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));
Если вам нужно отсортировать список на месте, вы можете использовать метод Sort
, передав делегат Comparison<T>
:
objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));
Если вы предпочитаете создавать новую, отсортированную последовательность, а не сортировать на месте, вы можете использовать метод LINQ OrderBy
, как указано в других ответах.
x
и y
на правую часть стрелки =>
.
– Jeppe Stig Nielsen
9 June 2016 в 08:13
Nullable<>
(возьмите DateTime?
в качестве примера) вы можете использовать .Sort((x, y) => Nullable.Compare(x.OrderDate, y.OrderDate))
, который будет обрабатывать нуль, как и все ненулевые значения. Это точно так же, как .Sort((x, y) => Comparer<DateTime?>.Default.Compare(x.OrderDate, y.OrderDate)
.
– Jeppe Stig Nielsen
30 January 2017 в 12:39
Пожалуйста, позвольте мне заполнить ответ @LukeH с некоторым примером кода, поскольку я его протестировал. Я считаю, что это может быть полезно для некоторых:
public class Order
{
public string OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int Quantity { get; set; }
public int Total { get; set; }
public Order(string orderId, DateTime orderDate, int quantity, int total)
{
OrderId = orderId;
OrderDate = orderDate;
Quantity = quantity;
Total = total;
}
}
public void SampleDataAndTest()
{
List<Order> objListOrder = new List<Order>();
objListOrder.Add(new Order("tu me paulo ", Convert.ToDateTime("01/06/2016"), 1, 44));
objListOrder.Add(new Order("ante laudabas", Convert.ToDateTime("02/05/2016"), 2, 55));
objListOrder.Add(new Order("ad ordinem ", Convert.ToDateTime("03/04/2016"), 5, 66));
objListOrder.Add(new Order("collocationem ", Convert.ToDateTime("04/03/2016"), 9, 77));
objListOrder.Add(new Order("que rerum ac ", Convert.ToDateTime("05/02/2016"), 10, 65));
objListOrder.Add(new Order("locorum ; cuius", Convert.ToDateTime("06/01/2016"), 1, 343));
Console.WriteLine("Sort the list by date ascending:");
objListOrder.Sort((x, y) => x.OrderDate.CompareTo(y.OrderDate));
foreach (Order o in objListOrder)
Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);
Console.WriteLine("Sort the list by date descending:");
objListOrder.Sort((x, y) => y.OrderDate.CompareTo(x.OrderDate));
foreach (Order o in objListOrder)
Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);
Console.WriteLine("Sort the list by OrderId ascending:");
objListOrder.Sort((x, y) => x.OrderId.CompareTo(y.OrderId));
foreach (Order o in objListOrder)
Console.WriteLine("OrderId = " + o.OrderId + " OrderDate = " + o.OrderDate.ToString() + " Quantity = " + o.Quantity + " Total = " + o.Total);
//etc ...
}
Вот общий метод расширения LINQ, который не создает дополнительную копию списка:
public static void Sort<T,U>(this List<T> list, Func<T, U> expression)
where U : IComparable<U>
{
list.Sort((x, y) => expression.Invoke(x).CompareTo(expression.Invoke(y)));
}
Чтобы использовать его:
myList.Sort(x=> x.myProperty);
Недавно я построил этот дополнительный один, который принимает ICompare<U>
, так что вы можете настроить сравнение. Это пригодилось, когда мне нужно было сделать естественную сортировку строки:
public static void Sort<T, U>(this List<T> list, Func<T, U> expression, IComparer<U> comparer)
where U : IComparable<U>
{
list.Sort((x, y) => comparer.Compare(expression.Invoke(x), expression.Invoke(y)));
}
OrderBy
делает все это внутренне.
– Servy
8 April 2014 в 22:08
void
в этом духе: static class Extensions { public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector) { self.SortBy(keySelector, Comparer<TKey>.Default); } public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) { self.Sort((x, y) => comparer.Compare(keySelector(x), keySelector(y))); } }
Может быть дополнен методом SortByDescending
. @ Замечания Servy применимы и к моему коду!
– Jeppe Stig Nielsen
30 January 2017 в 12:59
Использовать LiNQ OrderBy
List<Order> objListOrder=new List<Order> ();
objListOrder=GetOrderList().OrderBy(o=>o.orderid).ToList();
Самый простой способ упорядочить список - использовать OrderBy
List<Order> objListOrder =
source.OrderBy(order => order.OrderDate).ToList();
Если вы хотите заказать несколько столбцов, например, следующий SQL Query.
ORDER BY OrderDate, OrderId
Чтобы достичь это вы можете использовать ThenBy
, как показано ниже.
List<Order> objListOrder =
source.OrderBy(order => order.OrderDate).ThenBy(order => order.OrderId).ToList();
Классическое объектно-ориентированное решение
Сначала я должен напомнить об удивительности LINQ ... Теперь, когда у нас это получилось
Вариант на JimmyHoffa ответ. С помощью дженериков параметр CompareTo
становится безопасным по типу.
public class Order : IComparable<Order> {
public int CompareTo( Order that ) {
if ( that == null ) return 1;
if ( this.OrderDate > that.OrderDate) return 1;
if ( this.OrderDate < that.OrderDate) return -1;
return 0;
}
}
// in the client code
// assume myOrders is a populated List<Order>
myOrders.Sort();
Эта сортировка по умолчанию пригодна для повторного использования, конечно. То есть каждому клиенту не требуется избыточно переписывать логику сортировки. Переключение «1» и «-1» (или логические операторы, ваш выбор) отменяет порядок сортировки.
this
больше нуля. Для целей сортировки ссылка на нулевой объект "меньше, чем" this
объект. Именно так я решил определить, как сортируются нули.
– radarbob
23 June 2017 в 02:03
// Полностью общая сортировка для использования с gridview
public List<T> Sort_List<T>(string sortDirection, string sortExpression, List<T> data)
{
List<T> data_sorted = new List<T>();
if (sortDirection == "Ascending")
{
data_sorted = (from n in data
orderby GetDynamicSortProperty(n, sortExpression) ascending
select n).ToList();
}
else if (sortDirection == "Descending")
{
data_sorted = (from n in data
orderby GetDynamicSortProperty(n, sortExpression) descending
select n).ToList();
}
return data_sorted;
}
public object GetDynamicSortProperty(object item, string propName)
{
//Use reflection to get order type
return item.GetType().GetProperty(propName).GetValue(item, null);
}
data.OrderBy()
. Немного легче, чем изобретать колесо.
– gunr2171
13 June 2013 в 02:41
Улучшена версия Роджера.
Проблема с GetDynamicSortProperty заключается в том, что они получают только имена свойств, но что произойдет, если в GridView мы используем NavigationProperties? он отправит исключение, так как находит NULL.
Пример:
«Employee.Company.Name;» сбой ... поскольку разрешает только «Name» в качестве параметра получить его значение.
Вот улучшенная версия, которая позволяет нам сортировать по свойствам навигации.
public object GetDynamicSortProperty(object item, string propName)
{
try
{
string[] prop = propName.Split('.');
//Use reflection to get order type
int i = 0;
while (i < prop.Count())
{
item = item.GetType().GetProperty(prop[i]).GetValue(item, null);
i++;
}
return item;
}
catch (Exception ex)
{
throw ex;
}
}
С точки зрения производительности лучше всего использовать отсортированный список, чтобы данные сортировались по мере добавления к результату. Другие подходы нуждаются, по крайней мере, в одной дополнительной итерации по данным, и большинство из них создают копию данных, поэтому будет затронута не только производительность, но и использование памяти. Не может быть проблемой с несколькими сотнями элементов, но будет с тысячами, особенно в тех службах, где одновременно может выполняться сортировка нескольких параллельных запросов. Посмотрите на пространство имен System.Collections.Generic и выберите класс с сортировкой вместо списка.
И избегайте общих реализаций, используя отражение, когда это возможно, это также может вызвать проблемы с производительностью.
//Get data from database, then sort list by staff name:
List<StaffMember> staffList = staffHandler.GetStaffMembers();
var sortedList = from staffmember in staffList
orderby staffmember.Name ascending
select staffmember;
listWithObjects = listWithObjects.OrderByDescending(o => o.Status).ToList();
достаточным для такого усилия? – Andrew Grinder 18 July 2014 в 16:52