I have an arraylist of Joda DateTimes like this:
List <DateTime> nextRemindersArray = new ArrayList<DateTime>();
nextRemindersArray.add(reminderOneDateTime);
nextRemindersArray.add(reminderTwoDateTime);
nextRemindersArray.add(reminderThreeDateTime);
I am trying to sort the dates in ascending order but I am having trouble:
I googled it and found this page:
https://cmsoftwaretech.wordpress.com/2015/07/19/sort-date-with-timezone-format-using-joda-time/
I tried it like this:
nextRemindersArray.sort(nextRemindersArray);
But it gives me the error:
Error:(1496, 37) error: incompatible types: List<DateTime> cannot be converted to Comparator<? super DateTime>
I then tried like this:
DateTimeComparator dateTimeComparator = DateTimeComparator.getInstance();
nextRemindersArray.sort(nextRemindersArray, dateTimeComparator);
and also like this:
nextRemindersArray.sort(nextRemindersArray, new DateTimeComparator());
but all have errors.
I tried the Joda time manual and that wasn't much help. How do I sort the array?
Thanks in advance for your help
What you are looking for is:
nextRemindersArray.sort(DateTimeComparator.getInstance());
But because DateTime already implements Comparable, you don't really need a comparator and you can simply use:
nextRemindersArray.sort(null); //uses natural sorting
//or probably more readable
Collections.sort(nextRemindersArray);
Note that a quick look at the documentation of List::sort would have shown you that the method expects only one argument and it has to be a Comparator (and not two arguments like in your question).
Lets say we have SomeClass with this method getCreatedDate() which returns a DateTime joda object.
For a List you can have a simple comparator:
private Comparator<Listing> byCreatedDate = Comparator.comparing(SomeClass::getCreatedDate);
Then in your code you can call:
...
listings.sort(byCreatedDate);
return listings;
...
Haven't tested it but ... the idea should be ok.
In Kotlin you would call listing.sortedBy { it.createdDate }
Related
I'm looking for a library/tool in order to be able to de/serialize Linq Expressions.
Is there some library over there?
Is already suported natively on .Net? How could I get an starter stuff code?
It is unclear what you want to serialize: the result of a Linq expression, or the expression that you can use on a sequence.
IEnumerable<MyCollectionItem> MyCollection = ...;
IEnumerable<MyItem> result = MyCollection.LinqQuery(...);
Do you want to serialize result? or do you want to serialize LinqQuery, so you can use it later on a different collection:
IEnumerable<MyItem> otherResult = OtherCollection.DeserializedLinqQuery()
The first is easy: convert result to List<MyItem> and serialize / deserizalize the list.
The second is not really possible, after all, a LinqQuery is nothing more than a (possible composite) extension function to IEnumerable
static class MyCollectionItemExtensions
{
public static IEnumerable<MyItem> MyLinqQuery(this IEnumerable<MyCollectionItem>(...)
{
...
}
}
MyLinqQuery is a function, only after you've applied it to a sequence you get an object over which you can enumerate. It's not easy serialize a function.
However if MyLinqQuery is IQueryable, your query is not a function that is applied to elements of MyCollection, but something that has an expression that are applied to elements of MyCollection. You can ask the IQueryable for its expression and serialize that one.
There are several answers about how to do this in the article on StackOverflow: Serializing and deserialize expression tress
my question is about the new java 8 collection streaming possibilities. I do have a sorted map with Date objects as keys. Now I have written the method below, which has to find the previous key in the keyset of a given Date. So iterating over the keyset in reverse order it would be the first date which is prior to the given search date. Here is my implementation:
private Date getPreviousKey(Date searchKey, Map<Date, SchluesselSum> timesAndSums) {
return timesAndSums.keySet().stream()
.sorted(Comparator.<Date>reverseOrder())
.filter(date -> date.before(searchKey))
.findFirst()
.orElse(null);
}
Now the problem is, that the call to .sorted(Comparator.reverserOrder()) returns a stream of java.lang.Object instead of Date and my compiler can't find .isLessOrEqual(...) in the .filter(...) call in the class Object.
How can I tell the .sorted method, or to be more precisely, the Comparator to return Date instead of Object?
Thank you in advance for any help!
The problem seemed to be due to your custom Date class.
Note however that if your map also happens to be a NavigableMap (all SortedMaps in the JDK are navigable), you can call NavigableMap#lowerKey:
private Date getPreviousKey(Date searchKey, NavigableMap<Date, SchluesselSum> timesAndSums) {
return timesAndSums.lowerKey(searchKey);
}
This will be more efficient (in terms of lines of code, readability and performance) than your current approach.
In my base-repository class
i wrote this function to make possible to retrive a sorted data collection from the DB.
T is a generic defined at Class level
public abstract class RepositoryBase<T>
where T : class
The code is this:
public IList<T> GetAll<TKey>(Expression<Func<T, bool>> whereCondition, Expression<Func<T, TKey>> sortCondition, bool sortDesc = false)
{
if (sortDesc)
return this.ObjectSet.Where(whereCondition).OrderByDescending(sortCondition).ToList<T>();
return this.ObjectSet.Where(whereCondition).OrderBy(sortCondition).ToList<T>() ;
}
My goal was to introduce a generic sort parameter so that i could call the function in this way:
repo.GetAll (model=>model.field>0, model=>model.sortableField, true)
i mean that i could specify the sorting field directly via anonymous function and so using Intellisense...
Unfortunately this function doesn't work as the last code line generate errors at compile time.
I tried also to call:
repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)
but this don't work.
How should i write the function to meet my goal?
i'm working with EF 5, c#, .NET 4.5
You're using ObjectSet which implements IQueryable<T>. That is extended by methods on System.Linq.Queryable, which accept Expression<Func< parameters. It is correct to use those Expression parameters, as you intend for execution to occur in the database, not locally.
A Func is an anonymous delegate, a .net method.
An Expression is a tree, which may be compiled into a Func, or may be translated into Sql or something else.
You showed us a really abstract use of the method, but not an actual use of the method, or the compiler error. I suspect the error you may be making is confusing the two type parameters.
You said:
repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)
But this generic parameter for this method represents the type of sortableField. If sortableField isn't a Model - this is wrong.
Instead, you should be doing something like this:
Repository<Person> myRepo = new Repository<Person>();
myRepo.GetAll<DateTime>(p => p.Friends.Count() > 3, p => p.DateOfBirth, true);
If specifying the sort type breaks your intended pattern of usage, consider hiding that key by using an IOrderer: Store multi-type OrderBy expression as a property
Stumped on this one. In Grails it seems one cannot define a default sort on multiple columns in domain mapping a la static mapping = { sort 'prop1 desc, prop2 asc' }, or { sort([prop1:'desc', prop2:'asc']) }. Only first column gets sorted, lame.
Similarly, when trying to Groovy sort a Grails findAllBy query on multiple columns, the second sort overrides the first.
def list = [[rowNum:2,position:3],[rowNum:1,position:2],[rowNum:3,position:1]]
list.sort{it.rowNum}.sort{it.position}
Obviously missing the boat on the latter case, the groovy sort. I have seen postings re: implementing comparable, but looking for something more concise if possible.
Here is a Groovy solution. Still essentially implementing a Comparator though.
list.sort { map1, map2 -> map1.rowNum <=> map2.rowNum ?: map1.position <=> map2.position }
Thanks to the link from GreenGiant, we see that the issue is closed as fixed as of version 2.3.
There is also example code:
static mapping =
{ sort([lastname:'asc', name:'asc']) }
It is working for me in 2.4.3
You can use String.format if you know max length. I assumed max 10 lenght:
list.sort { String.format('%010d%010d', it.rowNum, it.position) }
When I call a Linq (not Linq-for-SQL, just simple in-memory Linq) - what locale it uses to compare objects, and how can I affect it?
E.g.
string[] a = { "a", "b", ... };
string max = a.Max();
What locale is used here - current, invariant? How can I affect it?
The comparision seems to be case-insensitive, what if I want to find case-sensitive max?
It uses the implementation of IComparable<string> in string.
You could fairly easily write your own version of Max which does take an IComparer<T> for comparisons - I'm very surprised there isn't one already. Alternatively, you could use Aggregate in a somewhat cumbersome way to accomplish the same result.
I decided to take a deeper look on what happening.
Max method uses Comparer class to compare items. Comparer class in turn uses GenericComparer.Compare method. This method calls String.CompareTo method. CompareTo uses following code:
CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, CompareOptions.None);
That said, you can affect behavior of Max method by changing
Thread.CurrentThread.CurrentCulture
If it's unacceptable, you have to roll out your own version of Max as Jon suggested.
Posting my code based on Jon's suggestion:
static T Max<T>(this IEnumerable<T> coll, IComparer<T> comp)
{
return coll.Aggregate((a, b) => comp.Compare(a, b) < 0 ? b : a);
}
It can be used as
string max = coll.Max(StringComparer.OrdinalIgnoreCase);