Consider this variable:
var myString = "kodjo play football";
alert(myString.length); // display myString length
alert(myString.toUpperCase()); // display characters as upper case
Here my concern:
We don't define this property and this method in our object myString. But we access them in it. Can someone give me more explanation?
Thanks
When you define some variable like var myVar = "text"; js detects what type of this variable, and after you can use all methods of current object.
So, if you create new variable myVarString = "text"; - type of this variable is String, but when you create variable myVarNotString = 5; this will an integer type, and in this case you can't use methods like string, so you can't use myVarNotString.length. But you can cast them to string and check length: var newString = myVarNotString.toString().length
Related
I'm new in Kotlin, and I want to create a multi dimensional array of a custom class, with null permitted. Something like that
private var array_map = arrayOf<Array<Obstacle?>>()
...
array_map[1][2] = Obstacle()
How can I do it? Thank you!
In case you need the index of each element in the constructor of the elements of the array:
Declaration:
var matrix: Array<Array<Obstacle?>>
Instantiation and initialization:
matrix = Array(numRows) { row ->
Array(numCols) { col ->
Obstacle(row, col)
}
}
You can use private var arrayMap: Array<Array<Obstacle?>> = arrayOf(). Just wrap with as much Array<> as you need.
Not sure if this is what you want, but imagine that Obstacle is a custom class with a field num as below
data class Obstacle(var num: Int){}
A 2D array of the Obstacle object would be as below:
val array: Array<Obstacle?> = arrayOf(Obstacle(123), Obstacle(234))
val arrayOfArray: Array<Array<Obstacle?>> = arrayOf(array)
println(arrayOfArray[0][0]) // would print Obstacle(num=123)
println(arrayOfArray[0][1]) // would print Obstacle(num=234)
So you should be declaring your 2D array as below
val arrayOfArray: Array<Array<Obstacle?>> = arrayOf()
Your code will compile as is. The problem is just that array size can't be changed and arrayOf<Array<Obstacle?>>() creates an empty array, so array_map[1][2] = Obstacle() fails at runtime. (Unless you do array_map = ... somewhere between them. Note that you should prefer val arrayMap, which can't be reassigned, unless you have a specific reason to use var.)
If you want your array to start with nulls, there is arrayOfNulls in the standard library, but it only creates a single-dimensional array, and what you really need is an array of arrays of nulls. You can write a helper function:
inline fun <reified T> matrixOfNulls(n: Int, m: Int) = Array(n) { arrayOfNulls<T>(m) }
private val arrayMap = matrixOfNulls<Obstacle>(5, 5) // example arguments
The approach I always use for this case is:
arr2D = Array(sizeA) { Array(sizeB) { content } }
Note I replaced the sizes by fields names to illustrate that each number/field represents the width and height length of each dimension of the 2D array.
Also, content should be replaced by the main content you want to fill in each coordinate, in your case seems you aims to setup with Obstacle() instances. If you want fill this content in other moment put null or a quick Any() reference.
In this last case, after creating that you can simply perform to set the itens:
arr2D[1][2] = Obstacle()
I'm trying to pass a const char * to an old C library converted from a Swift string in Swift.
This is the C function I'm calling:
artnet_node artnet_new(const char *ip, int verbose) { ...
how can I convert a Swift string to this const char type? It works when I pass ipAddress like this:
internal var ipAddress = "192.168.1.43"
but dit does not work when I pass it like this
internal var ipAddress:String = "192.168.1.43"
I need this in a function where I need to specify the type:
internal func setupArtnode(ip:String) -> Int{
I tried using AnyObject instead of String but that doesn't work either.
Thanks.
You should be able to pass a String directly to a C function expecting const char * and it will be automatically converted to a null-terminated UTF-8 string:
let string = "string"
let node = artnet_new(string, 1)
See Interacting with C APIs for more information. Here is the relevant excerpt:
When a function is declared as taking an UnsafePointer argument,
it can accept any of the following:
A String value, if Type is Int8 or UInt8. The string will automatically be converted to UTF8 in a buffer, and a pointer to that
buffer is passed to the function.
Not sure why but this code is working. This passes a string to a C function expecting a const char* which seems to be the same as a unsafePointer.
internal func setupArtnode(ipAddress:String) -> NSInteger{
let cString = self.ipAddress.cString(using: String.defaultCStringEncoding)!
let newString:String = NSString(bytes: cString, length: Int(ipAddress.characters.count), encoding:String.Encoding.ascii.rawValue)! as String
let key2Pointer = UnsafePointer<Int8>(newString)
node = artnet_new(key2Pointer, Int32(verbose)) // VERBOSE : true(1) , false(0)
...
Simple way for Swift 3
var ipAddress: String = "192.168.1.43"
var verbose: Int = 1
artnet_node artnet_new((ipAddress as NSString).utf8String, verbose)
You didn't specify what your Swift array contains. In any case, you need to convert your Swift array to an array of Int8:
let str = "Hello world"
let cArray = str.cString(using: .utf8)
artnet_new(cArray, 1)
I'm making a deck and card class for a game, and have encountered an error in creating and using a string array.
my code looks like this: The error is 4 lines from the bottom where it says String undealt = ... undealt[0] and it says "array required, but java.lang.String found" and now I am confused
import java.util.*;
public class Deck
{
private static int currentCard = 0;
public ArrayList<Card> deck;
private String rank;
private String suit;
private String[] undealt = new String[52];
Deck(String[] ranks, String[] suits, int[] values)
{
for(int i = 1; i <= suits.length; i++)
{
for(int x = 0; x < ranks.length; x++)
{
Card card = new Card(ranks[x], suits[i], values[x]);
deck.add(card);
}
}
shuffle();
}
public String toString()
{
String undealt = "Undealt cards:\n" + undealt[0] + undealt[1] ...;
for(int i = currentCard; i < deck.size(); i++)
{
int g = i - currentCard;
undealt[g] = deck.get(i).toString();
}
}
The problem which you are having derives from these lines in your code:
private String[] undealt = new String[52];
:
:
public String toString() {
String undealt = "Undealt cards:\n" + undealt[0] + undealt[1] ...;
:
:
}
As you can see, you have defined the variable undealt in two different scopes. The first declaration is at the instance level, where you have declared undealt to be an instance field of type String[]. The scope of an instance variable is the entire class in which it is defined, i.e. an instance variable can be accessed by all methods in that class.
The second declaration is at the local block level, where you have declared undealt to be a local variable of type String. The scope of a local variable is limited to the block in which it is declared (blocks are delimited by curly braces).
As you can see, undealt is in scope twice in the method toString(), once as an instance field, the second time as a local variable. The compiler has rules which it uses to resolve variable names when they conflict in this way, and will use the local variable definition. This is called "hiding" the instance field, i.e. the local variable hides the instance field.
When the compiler tries to compile...
String undealt = "Undealt cards:\n" + undealt[0] + undealt[1] ...;
it determines that String[] undealt is hidden, and it will resolve undealt as type String.
Therefore, when you attempt to use the array element access operator (the brackets after the variable name), the compiler gives you an error. It has determined that undealt is a local String and therefore it does not have any array elements to access.
A good practice is to avoid ever using two variables with the same name in order to avoid potential sources of confusion such as this. The compiler has a set of rules to use to resolve variable accesses in the case of a conflict, but these needn't be obvious to programmers and can cause confusion.
I want to read four cyclic measured sensors from an arduino and want to display the values with Processing.
My problem is, I get the error message: "Cannot find a class or type named 'Array' " in my processing code when I want to convert my data string into an array.
Does anybody know how to fix it?
import processing.serial.*;
Serial myPort;
String Messdaten;
String MessdatenSplit;
void setup () {
size(500, 500);
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw(){
}
void serialEvent(Serial myPort){
if (myPort.available() > 0){
String Messdaten = myPort.readStringUntil(3000);
if (Messdaten != null){
trim(Messdaten);
String MessdatenSplit[] = split(Messdaten,",");
MessdatenSplit = new Array[1400];
Natrium = new String[350];
Kalium = new Array[350];
Lithium = new Array[350];
Kupfer = new Array[350];
for (n=0; n<350; n++){
Natrium[n] = 1+4*n;
}
for (k=1; k<350; k++){
Kalium[k] = 1+4*k;
}
for (u=2; u<350; u++){
Kupfer[u] = 1+4*u;
}
for (l=3; l<350; l++){
Lithium[l] = 1+4*l;
}
}
}
}
There is no class named Array (well, there is, but it's not the one you want). That's not how you declare an array.
You declare an array variable by using the type of array you want, then using square brackets []. For example, you're declaring this variable:
String MessdatenSplit;
This declares the MessdatenSplit variable as String, not an array of Strings. Instead, you probably want this:
String[] MessdatenSplit;
Then when you initialize the MessdatenSplit variable, you should again use the type of array it is, and you should also use the square brackets and put the length of the array inside those square brackets. Here you're doing it correctly:
Natrium = new String[350];
(Although, you're missing a declaration for this variable, so you need to add that in for this to really work.)
The above line creates a String array with 350 indexes. But in this next line, and in a few other places, you're initializing it incorrectly:
MessdatenSplit = new Array[1400];
There is no Array keyword. You need to use the type of array it is, like this:
MessdatenSplit = new String[1400];
Note that you can also do the variable declaration and initialization in a single line:
String[] MessdatenSplit = new String[1400];
You might want to start over and declare and initialize a single array variable, then run it to make sure it works. Then add the next array, and run it to see if it works. You're running into trouble because you're trying to write and run your whole sketch at once, when really you need to be testing much smaller steps. Also, you should try to follow standard naming conventions: variables and functions should start with a lower-case letter.
So I'm having trouble figuring out how to compare two arrays for differences and be able to find which elements do not exist in each other. Most examples talk about object lookup for use with a "for each in" loop. That much makes sense, but I have no idea what is going on here:
var item:Sprite;
object_lookup[item] = true;
I'm quite confused because I've never seen anything other than an integer inside of [] such as with arrays.
Object is a dynamic, that means you can assign properties to it at runtime:
var o:Object = {};
o.sayHi = "Hi, it's me";
trace(o.sayHi); //traces: Hi, it's me
o.sayHiWithFunction = function () { return "Hi with function" };
trace(o.sayHiWithFunction()); //traces: Hi with function
If the property you want to assign is not a valid identifier, you have to use the [] and put it as a string, example:
var o:Object = {};
o.this = "Yes, it is this!"; // Error, this is a keyword! Won't compile
o["this"] = "And the correct this!"; //And this one works!
o["more words"] = "More words"; //Works too
Your code is confusing. If object_lookup is an Object instance, you created a property on it called null but you set this property to true. That means that it will have absolutely nothing to do with the Sprite item you declared above it. Which is null, of course, as you didn't assign a sprite object to it and that's why the property name gets evaluated to null. Do not confuse here: the property name "null" is just a string, it has nothing to do with the type null.
Now, the for in loop loops thru all the property names of an Object, and if you know the property names, you can actually look up the values, too. Looks something like this:
var o:Object = {a:"A", b:"B", c:"C"}; // This is equivalent to o.a = "A", o.b = "B", o.c = "C"... which is aquivalent to o["a"] = "A" ;)
for(var i in o) {
trace(i, o[i]) //traces: c C, a A, b B
}
The for each in is a bit different, if you trace i, you will see the values, not the property names as with for in loop.
Otherwise do what Vesper suggested you in the comment, read about Dictionary.