Is there a way to iterate on class members defined in a statics block? For example, if I have the following class definition:
qx.Class.define("app.MyEnumeration", {
type: "static",
statics: {
ENUM_VALUE_1: 1,
ENUM_VALUE_2: 2,
ENUM_VALUE_3: 3
}
}
Can I iterate on those members somehow? Something like this:
for (var i = 0; i < app.MyEnumeration.statics.length; i++)
doSomething(app.MyEnumeration.statics[i]);
There is not a specific API, but you can do it easily enough in code by iterating the properties of a class, eg:
Object.keys(qx.util.ColorUtil).forEach(function(key) {
console.log(key);
});
or, using your example:
for (var i = 0, arr = Object.keys(app.MyEnumeration); i < arr.length; i++)
doSomething(app.MyEnumeration[arr[i]])
Related
After experimenting with the reduce method to flatten an array, I tried using a similar approach with a for-loop.
Can anyone explain why the for-loop doesn't flatten the array using concat?
P.S. I know that I can use a nested for-loop with Array.isArray to flatten as well. Just expected concat to work in a for-loop after seeing how reduce flattened the array.
var arrays = [
[1, 2, 3],
[4, 5],
[6]
];
console.log(arrays.reduce(function(arr, elem) {
return arr.concat(elem);
}, []));
function flatten(arr) {
var flat = [];
for (var i = 0; i < arr.length; i++) {
flat.concat(arr[i]);
}
return flat;
}
console.log(flatten(arrays));
concat doesn't modify the array. To make your code work, you'd have to assign the value to it, then it'll do the same
var arrays = [[1,2,3], [4,5], [6]];
function flatten(arr) {
var flat = [];
for (var i = 0; i < arr.length; i++) {
flat = flat.concat(arr[i]);
}
return flat;
}
console.log(flatten(arrays));
Just a sidenote - with ES6, you can flatten an array even easier using the spread operator [].concat(...arr);
var arrays = [[1,2,3], [4,5], [6]];
function flatten(arr) {
return [].concat(...arr);
}
console.log(flatten(arrays));
And nowadays even easier, using flat()
const arrays = [[1,2,3], [4,5], [6]];
console.log(arrays.flat());
Please take a look at my 2D-Array-Initialization. The code works.
class World(val size_x: Int = 256, val size_y: Int = 256) {
var worldTiles = Array(size_x, { Array(size_y, { WorldTile() }) })
fun generate() {
for( x in 0..size_x-1 ) {
for( y in 0..size_y-1 ) {
worldTiles[x][y] = WorldTile()
}
}
}
}
The problem is that it runs the initialization twice. Basically I want to instantiate the WorldTile-Object in the generate() function. So Line 3 shouldn't call "new WorldTile" there. How can I do that?
Also is that the proper Kotlin way of traversing a 2d-Array?
You can make worldTiles a lateinit property, and do all the initialization in the generate function:
class World(val size_x: Int = 256, val size_y: Int = 256) {
lateinit var worldTiles: Array<Array<WorldTile>>
fun generate() {
worldTiles = Array(size_x, {
Array(size_y, {
WorldTile()
})
})
}
}
If you try to access worldTiles before calling generate you will get an exception warning that it hasn't been initialized yet.
To initialise all to a fixed value:
// A 6x5 array of Int, all set to 0.
var m = Array(6) {Array(5) {0} }
To initialise with a lambda:
// a 6x5 Int array initialise i + j
var m = Array(6) { i -> Array(5) { j -> i + j } }
Another way: Here is an example of initialising a 2D array of Float numbers (3 by 6):
var a = Array(3) { FloatArray(6)} // define an 3x6 array of float numbers
for(i:Int in 0 until a.size) {
for(j : Int in 0 until a[i].size) {
a[i][j] = 0f // initialize with your value here.
}
}
val twoDimStringArray= arrayOf(
arrayOf("first","second"),
arrayOf("foo"),
arrayOf("bar","great kotlin")
)
for (i in twoDimStringArray){
for(j in i){
println(j)
}
}
first
second
foo
bar
great kotlin
A bit late but could help to somebody if is working with strings
//init 2d array with a fixed size:
var data2 = Array<Array<String>>(2) { arrayOf()}
// fill the 2d array
data2[0] = arrayOf("123","Freddy x","27")
data2[1] = arrayOf("124","Elon y","45")
cheers!
public Update() {
this.Data = this.Items;
console.log(this.Data);
for (let value of this.Data) {
console.log(value);
}
}
console
[Object, Object, Object]
Object
CandidateName:"B"
ControlId:0
CreatedBy:null
CreationDateTime:null
ExamId1:2000
ExamName:" Safety"
Id:1292353
after last object it showing length:3
when i going to loop over this object,it is throwing error length is undefined,please help me.
If I understand correctly, this.Items is probably undefined in some cases and you cannot iterate.
So:
for (let value of (this.Data || [])) {
This guards against bad values
The for in or for of statement should be avoided for iterating over arrays. It has two "drawbacks":
1) The order is not guarantee
2) Also inherited properties will be listed/enumerated, if enumerable:false is not specified when defining the property.
If for example you add a property to your prototype, this loop will iterate also over that one.
Array.prototype.test = "test";
var a = ['a', 'b'];
for (let i in a) {
console.log(a[i]);
}
for (let i of a) {
console.log(i);
}
You should see also your property printed.
If you change your loop into a sequential for loop:
for (let i = 0; i < this.Data.length; i++ value of this.Data) {
console.log(this.Data[i]);
}
or a:
this.Data.forEach((el) => {
console.log(el);
});
you may not see your issue.
If you want to iterate over objects, You must use Object.keys(your_obj). Because object doesn't have length property. You can iterate through only of type 'Array' or 'String' using for of. You can use Object.keys(your_obj).length for sequential for loop for(var i=0; i<Object.keys(your_obj).length; i++)
public Update() {
this.Data = this.Items;
console.log(this.Data);
for (let obj of this.Data) {
console.log(obj);
//iterate over object here
for(let property of Object.keys(obj)){
// write your logic for specific object
}
}
}
Extension to quirimmo's answer, sequential for loop, use this
this.Data.forEach(function(obj){
console.log(obj);
//iterate over object here
for(var i=0; i<Object.keys(obj).length; i++){
// write your logic for specific object
}
})
How do i make 1 array that has the keys of 1st array & its values are the values of the 2nd array in Actionscript 3.0?
Below is my [WRONG] code. Package import left out.
public class myPages extends Sprite {
protected var pageNames:Array = [];
protected var pageLayoutNo:Array = [];
private var pageLayoutNames:Object = new Object();
public function assignNamesLayouts {
//all the names of the pages
for(i=0; i<totalPages; i++) {
var pageMc:MovieClip=new MovieClip();
pageMc.name = menu.config.pages.page[i].#name;
pageNames[i]= pageMc.name;
}
//all layout numbers
for(i=0; i<totalPages; i++) {
pageLayoutNo[i] = menu.config.layoutNum.layNum[i];
}
setNames(pageNames);
setPLNo(pageLayoutNo);
setLayoutNames(pageLayoutNo,pageNames);
}
protected function setNames(a:Array) {
pageNames = a;
}
protected function setPLNo(a:Array) {
pageLayoutNo = a;
}
protected function setLayoutNames(a:Array, b:Array) {
var maps:Object = new Object();
maps.no = a;
maps.nm = b;
for each(var k:int in a) {
maps[k] = b;
}
}
}
Thank you.
I will agree with #Vesper. Closest solution to the associative array will be Dictionary. I also will add, some ideas for you. If your collection will have keys as Strings, you could use simple Object:
var keyName: String = "key1";
var anotherKey: String = "key2";
var collection: Object = {};
collection[keyName] = new MovieClip();
collection[anotherKey] = new Sprite();
trace(collection[keyName]);
If you want to use 2 arrays: one for keys, another one for values, you will need several functions(place object with key, get object by key, get object by value, remove object by key, etc.) to manage them, because indexes in arrays must be identical.
Dictionary is really what you want, but you could do it by creating an array of objects like this:
var newArray=combineArrays("name", arr1,"number",arr2);
function combineArrays(name1, arr1,name2, arr2){
var newArr=new Array();
for(var i<arr1){
var obj=new Object();
obj[name1]=arr1[i];
obj[name2]=arr2[i];
newArr.push(obj);
}
}
Then you can search on the object names or values for either object.
Unfortunately in Actionscript, it seems like support for the Vector class isn't fully there yet. There are some scenarios where I need to convert a Vector into an array (creating an ArrayCollection for example). I thought this would do the trick:
var myVector:Vector.<MyType> = new Vector.<MyType>();
var newArray:Array = new Array(myVector);
Apparently this just creates an array where the first index of the array contains the full Vector object. Is this my only option:
var newArray:Array = new Array(myVector);
for each(var item:MyType in myVector)
{
newArray.push(item);
}
I feel like that clutters up the code a lot and I need to do this in a lot of places. The Vector class doesn't implement any kind of interface, so as far as I can tell I can't create a generic function to convert to an array. Is there any way to do this without adding this mess every time I want to convert a Vector to an array?
There's no easy/fast way to do it, the best solution is to use an utility class like this one:
package {
public class VectorUtil {
public static function toArray(obj:Object):Array {
if (!obj) {
return [];
} else if (obj is Array) {
return obj as Array;
} else if (obj is Vector.<*>) {
var array:Array = new Array(obj.length);
for (var i:int = 0; i < obj.length; i++) {
array[i] = obj[i];
}
return array;
} else {
return [obj];
}
}
}
}
Then you just have to update your code to something like this:
var myArray:Array = VectorUtil.toArray(myVector);
Paul at Work found a better way to do it.
var newArray:Array = [].concat(myVector);