Нам понадобился естественный вид для обработки текста со следующим шаблоном:
"Test 1-1-1 something"
"Test 1-2-3 something"
...
По какой-то причине, когда я впервые посмотрел на SO, я не нашел этот пост и не реализовал наш своя. По сравнению с некоторыми из представленных здесь решений, в то время как аналогичные по понятию, это могло бы иметь преимущество, возможно, быть более простым и понятным. Тем не менее, хотя я пытался посмотреть на узкие места производительности, он по-прежнему намного медленнее, чем по умолчанию OrderBy()
.
Вот способ расширения, который я реализую:
public static class EnumerableExtensions
{
// set up the regex parser once and for all
private static readonly Regex Regex = new Regex(@"\d+|\D+", RegexOptions.Compiled | RegexOptions.Singleline);
// stateless comparer can be built once
private static readonly AggregateComparer Comparer = new AggregateComparer();
public static IEnumerable<T> OrderByNatural<T>(this IEnumerable<T> source, Func<T, string> selector)
{
// first extract string from object using selector
// then extract digit and non-digit groups
Func<T, IEnumerable<IComparable>> splitter =
s => Regex.Matches(selector(s))
.Cast<Match>()
.Select(m => Char.IsDigit(m.Value[0]) ? (IComparable) int.Parse(m.Value) : m.Value);
return source.OrderBy(splitter, Comparer);
}
/// <summary>
/// This comparer will compare two lists of objects against each other
/// </summary>
/// <remarks>Objects in each list are compare to their corresponding elements in the other
/// list until a difference is found.</remarks>
private class AggregateComparer : IComparer<IEnumerable<IComparable>>
{
public int Compare(IEnumerable<IComparable> x, IEnumerable<IComparable> y)
{
return
x.Zip(y, (a, b) => new {a, b}) // walk both lists
.Select(pair => pair.a.CompareTo(pair.b)) // compare each object
.FirstOrDefault(result => result != 0); // until a difference is found
}
}
}
Идея состоит в том, чтобы разбить исходные строки на блоки цифр и цифр ("\d+|\D+"
). Поскольку это потенциально дорогостоящая задача, она выполняется только один раз для каждой записи. Затем мы используем сопоставитель сопоставимых объектов (извините, я не могу найти более правильный способ сказать это). Он сравнивает каждый блок с соответствующим блоком в другой строке.
Мне хотелось бы получить отзывы о том, как это можно улучшить и каковы основные недостатки. Обратите внимание, что ремонтопригодность важна для нас в данный момент, и мы в настоящее время не используем это в чрезвычайно больших наборах данных.
Исходя из того, что вы упомянули Xamarin , я думаю, вы должны работать над мобильным приложением.
В основном у вас есть четыре варианта, если вы хотите построить его с помощью AEM:
Я настоятельно рекомендую взглянуть на поддержку SPA или возможности PhoneGap, если вы не используете AEM 6.4.
Работа с Sling API или создание собственного API - не лучший вариант, если вы новичок в AEM. Существует так много подводных камней, которые вызовут у вас много головной боли, и вы рискуете создать неразрешимый беспорядок в проекте AEM.