I need to convert values of type T into JsArray.
For example, I have String1, String2 .... Stringn. I need to convert these Strings into JsArray string.
How can I implement this?
You don't have much choices: creating a JsArrayString and adding to it, or using JSNI.
JsArrayString arr = JavaScriptObject.createArray().cast();
arr.push(str1);
arr.push(str2);
arr.push(str3);
or
static native JsArrayString asJsArray(String str1, String str2, String str3) /*-{
return [str1, str2, str3];
}-*/;
Obviously, the latter doesn't scale, while being faster.
It really depends what exactly you need to do.
Use JsArrayUtils like this:
JsArray<String> arr = JsArrayUtils.readOnlyJsArray(new String[] { string1, string2 });
Take a look at the javadoc:
com.google.gwt.core.client.JsArrayUtils
Utility class for manipulating JS arrays. These methods are not on
other JavaScriptObject subclasses, such as JsArray, because adding new
methods might break existing subtypes.
Using generics, could do it like this:
public <T extends JavaScriptObject> JsArray<T> createGenericArray(T... objects) {
JsArray<T> array = JavaScriptObject.createArray().cast();
for (T object : objects) {
array.push(object);
}
return array;
}
Obviously, String doesn't extend JavaScriptObject. You'd need to have overloads to account for primitive types. (Or, less safely, you could remove the bounds of T to allow for arbitrary types. You'd need to be much more careful if you were to do so.)
Related
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
In C# I can do this:
public string[] MyStrings;
...
...
if(MyStrings.Contains("bob")) ...
In ObjectScript how is this done?
With %ArrayOfObjects type I don't see exactly what I am looking for here
What I have tried:
#Dim MyStrings As %ArrayOfDataTypes
do MyStrings.SetAt("User","User")
do MyStrings.SetAt("Users","Users")
do MyStrings.SetAt("Group","Group")
do MyStrings.SetAt("Groups","Groups")
// if MyStrings contains Groups
if MyStrings.GetAt("Groups") '= ""
{
}
It sounds like you want the .IsDefined() method. For example:
#Dim MyStrings As %ArrayOfDataTypes
do MyStrings.SetAt("User","User")
do MyStrings.SetAt("Users","Users")
do MyStrings.SetAt("Group","Group")
do MyStrings.SetAt("Groups","Groups")
// if MyStrings contains Groups
if MyStrings.IsDefined("Groups")
{
// code to execute if MyStrings contained "Groups"
}
You've got it right. I would suggest making a subclass of %Library.ArrayOfDataTypes with your own methods on it, such as "contains".
It's probably a little safer to use your own classes that you do control than library classes that you don't anyway (though in a pinch you could always use %Dictionary package methods to switch all references to a library class to a new class of your design, so it's not really that big a deal).
I am not familiar with that language, but could you try something like:
//declare myString to hold a string
set myString = MyStrings.GetNext("")
While myString '= ""
{
if MyStrings.GetAt(myString) '= "" //Or should it be something like myString.value? Is there a way to check the type of an object to see if it is a string?
{
//Do something here. Exit loop if you are trying to find just a match.
}
}
I am assuming '= is equivalent to != in C#.
I have a design issue which has proven to bee too much for my current design skills.
I hope my request is not too trivial or too stupid for the incredibly skilled people I saw in these forums over time.
Basically, this is what I need:
to be able to reference a specific class instantiation by means of another class static or constant declaration (hope it makes as much sense to you as it does to me, hah).
The 'enum' behavior would be particularly useful for its 'ease of access' and for its standard methods.
//simple class with a constructor
public class myclass {
int myint = 0;
string mystring = "";
public myclass(int localint, string localstring) {
myint = localint;
mystring = localstring;
}
}
//the core of the issue.
public enum myenum : myclass {
enum1 = new myclass(9,"abr"),
enum2 = new myclass(99,"acad"),
enum3 = new myclass(999,"abra")
}
So that elsewhere, when I need 'abra', instead of manually instantiating it, and having countless duplicates all over the code, I just
myenum mylocalenum;
mylocalenum = enum3; //no mistake, the underlying class variables are predefined
The purpose is to have a selectable, pre-set 'myenum' which basically encapsulates another data structure which I predefine in the declaration phase.
This is because I have several data pre-sets by design, and I need to interact with them as with an enum (get their number, their descriptions, and basically associate them with predefined values).
If you have a solution, or even a resembling alternative, please let me know.
I have a class method that returns a pointer to an inner data structure (where the data structure is guaranteed to outlive its use in python code). It looks like:
class MyClass {
...
some_structure* get() {
return inner_structure_;
}
private:
some_structure* inner_structure_;
};
I want to wrap this get() method in Boost::Python so that if two different objects of this class return the same pointer, the associated some_structure objects in python compare equal.
Inside the class_<MyClass> definition I've tried wrapping get() with both return_value_policy<reference_existing_object>() and return_inner_reference<>() call policies, but in both cases, calling get() on different python "MyClass" objects returns different some_structure objects even though all point to the same memory address in C++.
How would I get around this? Might there be a hidden property inside the wrapper object that stores the pointer's address, so I can compare those instead?
Figured out a way to do it, although it still feels hackish and that there should be some easier way. But here goes:
1) Define your own methods that compare the pointers.
template <typename T>
bool eq(const T* self, const T* rhs) {
return self == rhs;
}
template <typename T>
bool ne(const T* self, const T* rhs) {
return !eq<T>(self, rhs);
}
2) Manually declare the __eq__ and __ne__ inside the wrapper class to point to those methods:
class_<smth>("smth", no_init)
...
.def("__eq__", &eq<smth>)
.def("__ne__", &ne<smth>);
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.