CoffeeScript has a lot of useful shorthand regarding arrays and objects with comprehensions and destructuring. is there a quick shorthand for comparing entire objects or multiple properties thereof? i.e.
activity.date() is selected.date() and activity.month() is selected.month()
would be something a little like
activity[date(), month()] is selected[date(), month()]
I haven't seen anything like that in the docs but I figured I'd ask.
I'm not aware of any such functionality in CoffeeScript itself, but the Underscore.js library includes an isEqual function for this:
var moe = {name : 'moe', luckyNumbers : [13, 27, 34]};
var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
moe == clone;
=> false
_.isEqual(moe, clone);
=> true
I'm afraid there's nothing like that, even more for function calls. You can use underscore's isEqual to achieve that.
Related
I have a CriteriaBuilder-based query that can be ordered by several different properties.
Currently it's being handled somehow like this:
when(filters.sortBy) {
"foo" -> query.orderBy(if(isAsc) cb.asc("bar") else cb.desc("bar"))
"baz" -> query.orderBy(if(isAsc) cb.asc("quux") else cb.desc("quux"))
}
It's definitely not the most readable or maintainable code I've ever written.
Is there a better and possibly more idiomatic way to do this in Kotlin, given that it doesn't have the ternary ? : operator?
Note that some of the properties I need to order by may be subproperties of the root object, so just extracting this to a method that takes a string as the name of the order clause may not be easy.
when is an expression, so you can use it's result directly as an argument in query.orderBy()
Also, local function would help to eliminate if-else duplication part
fun query(...) {
...
fun sort(name: String) = if (isAsc) cb.asc(name) else cb.desc(name)
query.orderBy(sort(
when (filters.sortBy) {
"foo" -> "bar"
"baz" -> "quux"
}
))
...
}
I get an error when I put the type and size of an array of classes
I have tried:
fun main(args :Array<String>) {
class modul() {
var nommodul: String? = null
var coeff: Int? = null
var note: Int? = null
}
var releve
class notes() {
var releve: array<modul>(10){""} here the erreur
}
}
First of all, your code has several errors. This might be an MCVE and/or copy-paste issue, but I need to address these before I get started on the arrays.
var releve before the notes class isn't allowed. You don't assign it, you don't declare a type, and the compiler will complain if you copy-paste the code from your question.
Second, the array var itself: Array is upper-case, and initialization is separate. This would be more valid (note that this still does not work - the solution for that comes later in this answer):
var releve: Array<modul> = Array(10) {...}
// or
var releve = Array<modul>(10) {...}
And the last thing before I start on the array itself: please read the language conventions, especially the naming ones. Your classes should all start with an upper-case letter.
Kotlin arrays are quite different from Java arrays in many ways, but the most notable one being that direct array initialization also requires an initializer.
The brackets are expected to create a new instance, which you don't. You create a String, which isn't, in your case, a modul.
There are several ways to fix this depending on how you want to do this.
If you have instances you want to add to the array, you can use arrayOf:
arrayOf(modulInstance, modulInstance2, ...)
If you want to create them directly, you can use your approach:
var releve = Array(10) { modul() }
A note about both of these: because of the initialization, you get automatic type inference and don't need to explicitly declare <modul>
If you want Java-style arrays, you need an array of nulls.
There's two ways to do this:
var releve = arrayOfNulls<modul>(10)
// or
var releve = Array<modul?>(10) { null }
I highly recommend the first one, because it's cleaner. I'm not sure if there's a difference performance-wise though.
Note that this does infer a nullable type to the array, but it lets you work with arrays in a similar way to Java. Initialization from this point is just like Java: releve[i] = modul(). This approach is mostly useful if you have arguments you want to add to each of the classes and you need to do so manually. Using the manual initializers also provides you with an index (see the documentation) which you can use while initializing.
Note that if you're using a for loop to initialize, you can use Array(10) { YourClass() } as well, and use the supplied index if you need any index-sensitive information, such as function arguments. There's of course nothing wrong with using a for loop, but it can be cleaner.
Further reading
Array
Lambdas
here some example of kotlin array initialization:
array of Library Method
val strings = arrayOf("January", "February", "March")
Primitive Arrays
val numbers: IntArray = intArrayOf(10, 20, 30, 40, 50)
Late Initialization with Indices
val array = arrayOfNulls<Number>(5)
for (i in array.indices) {
array[i] = i * i
}
See Kotlin - Basic Types for details
I'm using the Mongo LINQ Driver for C#, works great.
Sorting a lot of properties but heres a problem I can't solve, its probably simple.
var identifierList = new []{"10", "20", "30"};
var newList = list.Where(x => identifierList.Contains(x.Identifier));
This is NOT supported ...
So I could do something like:
var newList = list.Where(x => x.Identifier == "10" || x.Identifier == "20" || x.Identifier == "30");
But since the list is variable ... how do I construct the above? Or are there even better alternatives?
The list is of type IQueryable<MyCustomClass>
For information ... this is used as a filter of alot of properties. In SQL I could have a parent -> child relationship. But as I can't as the parent for the main ID I need to take all the ID's out and then construct it like this.
Hopes this makes sense. If needed I will explain more.
To answer my own question ... The Mongo Sharp LINQ driver has an extension method called "In" which does exactly what I need.
They have however implemented it in 1.5 so we can use the old way like: https://jira.mongodb.org/browse/CSHARP-462
var list = new []{"10", "10"};
search.Where(x => list.Contains(x.Id));
But the version 1.5 package is not on nuget yet.
However, this should work with the "In" extension that comes as a special surprise with the mongo-csharp-driver.
search.Where(x => x.In(list));
var identifierList = new []{"10", "20", "30"};
var newList = list.ToList().Where(x => identifierList.Contains(x.Identifier));
You will just have to use List instead of Ienumerable (do that by using the .ToList())
If it doesn't work please add your list TYPE
In a Meteor application I have an event that should update the database data for changed fields on a form.
So the event handler looks like this:
Template.someTemplate.events({'change #someForm' : function(){
eval("someCollection.update(Session.get(\"currentId\"), {$set: {" + event.target.name + ":event.target.value}});");
}})
This works fine, when I use eval. But I doubt it is considered a best practice to use eval like this, or is it?
How would I have to write the MongoDB-update code, to make something like the following work?
Template.someTemplate.events({'change #someForm' : function(){
var variableName = event.target.name;
someColletion.update(Session.get("currentId"), {$set: {variableName:event.target.value}});
}})
Or what is the right way, to approach this? (The code above does not work, as for the MongoDB update instruction the variableName is not evaluated, so "variableName" is passed instead of its set value.
Note that I want to use this for prototyping, not actually a real application. So security is actually not really an issue. (I am a UX guy, not a software engineer.)
You need to create the object using indexer notation:
var param = { $set: {} };
param.$set[event.target.name] = event.target.value;
someCollection.update(Session.get("currentId"), param);
I have two methods like so:
Foo[] GetFoos(Type t) { //do some stuff and return an array of things of type T }
T[] GetFoos<T>()
where T : Foo
{
return GetFoos(typeof(T)) as T[];
}
However, this always seems to return null. Am I doing things wrong or is this just a shortfall of C#?
Nb:
I know I could solve this problem with:
GetFoos(typeof(T)).Cast<T>().ToArray();
However, I would prefer to do this wothout any allocations (working in an environment very sensitive to garbage collections).
Nb++:
Bonus points if you suggest an alternative non allocating solution
Edit:
This raises an interesting question. The MSDN docs here: http://msdn.microsoft.com/en-us/library/aa664572%28v=vs.71%29.aspx say that the cast will succeed if there is an implicit or explicit cast. In this case there is an explicit cast, and so the cast should succeed. Are the MSDN docs wrong?
No, C# casting isn't useless - you simply can't cast a Foo[] to a T[] where T is a more derived type, as the Foo[] could contain other elements different to T. Why don't you adjust your GetFoos method to GetFoos<T>()? A method only taking a Type object can easily be converted into a generic method, where you could create the array directly via new T[].
If this is not possible: Do you need the abilities an array offers (ie. indexing and things like Count)? If not, you can work with an IEnumerable<T> without having much of a problem. If not: you won't get around going the Cast<T>.ToArray() way.
Edit:
There is no possible cast from Foo[] to T[], the description in your link is the other way round - you could cast a T[] to a Foo[] as all T are Foo, but not all Foo are T.
If you can arrange for GetFoos to create the return array using new T[], then you win. If you used new Foo[], then the array's type is fixed at that, regardless of the types of the objects it actually holds.
I haven't tried this, but it should work:
T[] array = Array.ConvertAll<Foo, T>(input,
delegate(Foo obj)
{
return (T)obj;
});
You can find more at http://msdn.microsoft.com/en-us/library/exc45z53(v=VS.85).aspx
I think this converts in-place, so it won't be doing any re-allocations.
From what I understand from your situation, using System.Array in place of a more specific array can help you. Remember, Array is the base class for all strongly typed arrays so an Array reference can essentially store any array. You should make your (generic?) dictionary map Type -> Array so you may store any strongly typed array also while not having to worry about needing to convert one array to another, now it's just type casting.
i.e.,
Dictionary<Type, Array> myDict = ...;
Array GetFoos(Type t)
{
// do checks, blah blah blah
return myDict[t];
}
// and a generic helper
T[] GetFoos<T>() where T: Foo
{
return (T[])GetFoos(typeof(T));
}
// then accesses all need casts to the specific type
Foo[] f = (Foo[])GetFoos(typeof(Foo));
DerivedFoo[] df = (DerivedFoo[])GetFoos(typeof(DerivedFoo));
// or with the generic helper
AnotherDerivedFoo[] adf = GetFoos<AnotherDerivedFoo>();
// etc...
p.s., The MSDN link that you provide shows how arrays are covariant. That is, you may store an array of a more derived type in a reference to an array of a base type. What you're trying to achieve here is contravariance (i.e., using an array of a base type in place of an array of a more derived type) which is the other way around and what arrays can't do without doing a conversion.