My client wants a list of every item with the name of the categories it belongs to in each appropriate column.
<cfscript>
arr = ArrayNew(1);
arr[1] = '';
arr[2] = 'category B';
stc["Item One"] = arr;
arr[1] = 'category A';
arr[2] = '';
stc["Item Two"] = arr;
arr[1] = 'category A';
arr[2] = 'category B';
stc["Item Three"] = arr;
writedump(stc);
for (element in stc) {
WriteOutput(element & '<br>');
// The next line produces:
// Object of type class java.lang.String cannot be used as an array
for (i=1; i<=ArrayLen(element); i+=1) {
}
}
</cfscript>
Q: How do I get to the arrays inside of each element?
In your example, you are using a for ... in loop to iterate through the keys of the struct, not the values. This can be a bit confusing, for the same syntax with an array will iterate through the elements.
In your code, you have placed the key string into element, which isn't the array. This is the reason why the error Object of type class java.lang.String cannot be used as an array is produced.
As RRK has answered, to access the value in the struct you need to use the syntax struct[keyOfItem].
//Loop keys in the struct
for (key in stc) {
writeOutput(key & '<br>');
//Loop items in the array
for(element in stc[key]){
writeOutput(element & '<br>');
}
}
You can access the arrays inside using [] representation.
stc[element] This will get you the array.
for (i=1; i<=ArrayLen(stc[element]); i+=1) {
writedump(stc[element][i]);
}
DEMO
Related
So I know I'm missing something obvious, however, after searching similar/related questions, I can't quite figure out what I'm doing wrong.
New to Kotlin, so probably something I'm not understanding properly.
Creating an ArrayList, as I need a growing list of items, starting with none. Think of it like an undo list. It'll grow to an unknown size. At some point, I'll reset it back to "empty" when needed.
Inside this list, I need an Array of Integers. These 3 values are a co-ordinate system - if it matters (ie x,y,z).
Everything I try, I keep ending up only being able to retrieve the final IntArray set added.
Using:
https://developer.android.com/training/kotlinplayground
fun main() {
// array list
var myList = arrayListOf<IntArray>()
// 3 item "test" array to populate array list with
var myArr = IntArray(3){0}
// setup Array list with 3 items
for ( b in 0..2 ) {
// fake/create a temp array with some simple values
for ( i in 0..2 ) { myArr[i] = 3+b+(3*i) }
// add it to the List
myList.add(b, myArr)
// confirm values
println ( "Added [" + myList.lastIndex +"] = " + myArr[0] +"-"+ myArr[1] +"-"+ myArr[2] )
}
// confirm size of Array List
println ( "size: " + myList.size )
// test pull the middle array from the ArrayList
// indices should be: 0, 1 and 2
var testArr = myList.get(1)
println ( "for idx 1: vals: " + testArr[0] +"-"+ testArr[1] +"-"+ testArr[2])
// test display all values for all arrays
myList.forEach {
println ( "Vals: " + it[0] +"-"+ it[1] +"-"+ it[2] )
}
// another method to do same ?
for ((index,value) in myList.withIndex()) {
println("index: $index ... " + value[0] +"-"+ value[1] +"-"+ value[2])
}
}
output is:
Added [0] = 3-6-9
Added [1] = 4-7-10
Added [2] = 5-8-11
size: 3
for idx 1: vals: 5-8-11
Vals: 5-8-11
Vals: 5-8-11
Vals: 5-8-11
index: 0 ... 5-8-11
index: 1 ... 5-8-11
index: 2 ... 5-8-11
Everything makes perfect sense up until the repeats of "5-8-11" .. what am I doing wrong?
I read your code, I think the problem is the IntArray you use, it is an object, every time you add it to the list, it is the same object. so In the end, it is always the same element.
please change the code to the following:
...
for ( b in 0..2 ) {
// fake/create a temp array with some simple values
var myArr = IntArray(3){0}
for ( i in 0..2 ) { myArr[i] = 3+b+(3*i) }
// add it to the List
myList.add(b, myArr)
// confirm values
println ( "Added [" + myList.lastIndex +"] = " + myArr[0] +"-"+ myArr[1] +"-"+ myArr[2] )
}
...
that should resolve your problem.
Here is the explanation of the reference object
As you work with objects, it's important to understand references.
A reference is an address that indicates where an object's variables and methods are stored.
You aren't using objects when you assign an object to a variable or pass an object to a method as an argument. You aren't even using copies of the objects. Instead, you're using references to those objects.
Here is the description about kotlin, it explains by image and content, you can read this.
The issue is that in:
for ( i in 0..2 ) { myArr[i] = 3+b+(3*i) }
you always modifying and adding the same object: myArr .
To fix, replace
for ( i in 0..2 ) { myArr[i] = 3+b+(3*i) }
with
val a = IntArray(3) { i -> 3+b+(3*i) }
and then add a:
myList.add(a)
Or, if populating the IntArray is as simple as in the example just:
myList.add(IntArray(3) { i -> 3+b+(3*i) })
The final code looks like this:
fun main() {
val myList = arrayListOf<IntArray>()
// setup Array list with 3 items
for ( b in 0..2 ) {
myList.add(IntArray(3) { i -> 3+b+(3*i) })
}
for ((index,value) in myList.withIndex()) {
println("index: $index ... " + value[0] +"-"+ value[1] +"-"+ value[2])
}
}
or even more concise (probably too much):
fun main() {
val myList = List(3) { b -> IntArray(3) { i -> 3 + b + (3 * i) } }
for ((index, value) in myList.withIndex()) {
println("index: $index ... " + value[0] + "-" + value[1] + "-" + value[2])
}
}
Creating an ArrayList, as I need a growing list of items, starting
with none. Think of it like an undo list. It'll grow to an unknown
size. At some point, I'll reset it back to "empty" when needed.
This sounds like you need a Stack. You could use a MutableList for this, or the ArrayDeque class. With size, addLast(element), clear, contains(element), isEmpty(), last() , and removeLast() you have everything at hand for manipulating something like an Undo list.
To construct it you would do:
val stack = ArrayDeque<IntArray>()
for (b in 0..2) {
val intArray = IntArray(3)
for (i in 0..2) {
intArray[i] = 3 + b + (3 * i)
}
stack.addLast(intArray)
}
stack.forEach { println(it.joinToString("-")) }
Output:
3-6-9
4-7-10
5-8-11
I'm trying to sort an entire list according to one property. Afterwards I'd like to sort this list according to a second property, but in groups of 4. So, after sorting the list once, I want to look at the first 4 positions and sort only these 4 according to the second property - then move on to the next 4 positions and sort these again, and so on...
This is what I have so far:
class myElements {
int Position;
String text;
int Top;
int Left;
myElements(int Position, String text, int Top, int Left){
this.Position = Position;
this.text = text;
this.Top = Top;
this.Left = Left;
}
}
var FirstList = new List<myElements>();
var newList = new List<myElements>();
Adding Elements to my first list:
myElements Test = myElements(ElementNumber, text, Top, Left);
FirstList.add(Test);
Then sorting for the first time according to 'Top':
Comparator<myElements> TextComparator = (a, b) => a.Top.compareTo(b.Top);
FirstList.sort(TextComparator);
Here is where I'm stuck. I'm trying to sort the list again, but only in groups of 4 - this time according to 'Left':
for (int i = 0; i < FirstList.length; i += 4) {
Comparator<myElements> TextComparator2 = (a, b) =>
a.Left.compareTo(b.Left);
newList.addAll(FirstList.sublist(i, i + 3).sort(TextComparator2)); //this line does not work
}
I think I am stuck trying to access my sorted sublist: (FirstList.sublist(i, i + 4).sort(TextComparator2) . If I could add these to a new list, it should work.
However any other suggestions are more than welcome.
Thanks so much!
newList.addAll(FirstList.sublist(i, i + 3).sort(TextComparator2)); //this line does not work
Your code is almost correct. You have the right idea, but you ended up trying to do too much in one line of code.
Breaking it down a bit, your code is equivalent to:
var sublist = FirstList.sublist(i, i + 3);
newList.addAll(sublist.sort(...)); // Does not work
And that doesn't work because List.sort does not return a value. It mutates the list instead of returning a new list.
It would work if you instead did:
var sublist = FirstList.sublist(i, i + 3);
sublist.sort();
newList.addAll(sublist);
Also, List.sublist uses an exclusive end index. If you want to create sublists with 4 elements, you would need to use sublist(i, i + 4).
I'm building a table of data. At first, the rows of this table are most easily filled by key / value so I use a hash
a = Hash(Int32, Symbol).new
a[1] = :one
Once that's done, it's more convenient to work with an array (I need to sort the data for example). Easy enough:
a.to_a # => [{1, :one}]
But now I'm discovering that for my formatter to work properly (multi-page table, using latex) things just make more sense if I can store another data type in that array, for example, a string. But it's too late! The type of the array is fixed; it won't admit a string.
a << "str" # => ERROR!
The solution I've come up with so far doesn't seem very elegant:
a = Hash(Int32, Symbol).new
a[1] = :one
arr = Array(String | Tuple(Int32, Symbol)).new
a.each do |k,v|
arr << {k,v}
end
arr << "str" # no problem now
Is there a more "Crystal" / elegant way?
Just use to_a with as it can be used to cast to a "bigger" type as the docs call it
a = Hash(Int32, Symbol).new
a[1] = :one
arr = a.to_a.map { |x| x.as(String | Tuple(Int32, Symbol)) }
arr << "str" # [{1, :one}, "str"]
I need to remove the first element from an array, that is present in a second array.
Looking through the std.algorithm package, I can get part way there with findAmong and remove.
But is there a way to combine these, so that I can both remove an element, and see which element was removed?
For example:
// array that will have elements removed
auto targetStrings = ["a", "b", "c"];
// holder for element that will be removed
string removedString;
// array to match against, to determine what should be removed
auto removeStrings = ["b", "a"];
auto r = findAmong(targetStrings, removeStrings);
if (r.count > 0) {
removedString = r[0];
targetStrings = targetStrings.remove!(c => c == removedString);
}
writeln(removedString);
writeln(targetStrings);
You can get the element's index by subtracting the length of the remaining range returned by findAmong from the length of the original range, and then just use remove with the index:
auto r = findAmong(targetStrings, removeStrings);
if (!r.empty)
{
removedString = r.front;
auto index = targetStrings.length - r.length;
targetStrings = targetStrings.remove(index);
}
Alternatively, get the index directly with countUntil:
auto index = targetStrings.countUntil!(s => removeStrings.canFind(s));
if (index >= 0)
{
removedString = targetStrings[index];
targetStrings = targetStrings.remove(index);
}
I'm looking every where on the web (dart website, stackoverflow, forums, etc), and I can't find my answer.
So there is my problem: I need to write a function, that print a random sort of a list, witch is provided as an argument. : In dart as well.
I try with maps, with Sets, with list ... I try the method with assert, with sort, I look at random method with Math on dart librabry ... nothing can do what I wana do.
Can some one help me with this?
Here some draft:
var element03 = query('#exercice03');
var uneliste03 = {'01':'Jean', '02':'Maximilien', '03':'Brigitte', '04':'Sonia', '05':'Jean-Pierre', '06':'Sandra'};
var alluneliste03 = new Map.from(uneliste03);
assert(uneliste03 != alluneliste03);
print(alluneliste03);
var ingredients = new Set();
ingredients.addAll(['Jean', 'Maximilien', 'Brigitte', 'Sonia', 'Jean-Pierre', 'Sandra']);
var alluneliste03 = new Map.from(ingredients);
assert(ingredients != alluneliste03);
//assert(ingredients.length == 4);
print(ingredients);
var fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort();
print(fruits);
There is a shuffle method in the List class. The methods shuffles the list in place. You can call it without an argument or provide a random number generator instance:
var list = ['a', 'b', 'c', 'd'];
list.shuffle();
print('$list');
The collection package comes with a shuffle function/extension that also supports specifying a sub range to shuffle:
void shuffle (
List list,
[int start = 0,
int end]
)
Here is a basic shuffle function. Note that the resulting shuffle is not cryptographically strong. It uses Dart's Random class, which produces pseudorandom data not suitable for cryptographic use.
import 'dart:math';
List shuffle(List items) {
var random = new Random();
// Go through all elements.
for (var i = items.length - 1; i > 0; i--) {
// Pick a pseudorandom number according to the list length
var n = random.nextInt(i + 1);
var temp = items[i];
items[i] = items[n];
items[n] = temp;
}
return items;
}
main() {
var items = ['foo', 'bar', 'baz', 'qux'];
print(shuffle(items));
}
You can use shuffle() with 2 dots like Vinoth Vino said.
List cities = ["Ankara","London","Paris"];
List mixed = cities..shuffle();
print(mixed);
// [London, Paris, Ankara]