Assigning values to ArrayList using mapTo - arraylist

Previously I was using this code:
private val mItems = ArrayList<Int>()
(1..item_count).mapTo(mItems) { it }
/*
mItems will be: "1, 2, 3, 4, 5, ..., item_count"
*/
Now, I am using a class instead of Int, but the class has Int member with name id.
class ModelClass(var id: Int = 0, var status: String = "smth")
So how can I use this method to fill the ArrayList in similar way?
//?
private val mItems = ArrayList<ModelClass>()
(1..item_count).mapTo(mItems) { mItems[position].id = it } // Something like this
//?

From the mapTo documentation:
Applies the given transform function to each element of the original collection and appends the results to the given destination.
Therefore, you just need to return the elements you want:
(1..item_count).mapTo(mItems) { ModelClass(it) }

If you are OK with any MutableList (which is often ArrayList or similar):
val mItems1 = MutableList(item_count) { i -> i }
val mItems2 = MutableList(item_count) { ModelClass(it) }

Related

How to use the spread operator with ArrayList in kotlin?

I've read the documentation and I run into this issue of using the spread operator with an ArrayList Collection, and I want to know how to solve the mismatch type or implement a way to use it with ArrayList
I'll attach an image of the code along with the code.
fun howSum(targetSum: Int, numbers: ArrayList<Int>): ArrayList<Int>? {
if (targetSum == 0) return arrayListOf();
if (targetSum < 0) return null;
for (number: Int in numbers){
val remainder = targetSum - number;
val remainderResult = howSum(remainder, numbers);
if (remainderResult != null){
return arrayListOf(*remainderResult, number)
}
}
return null
}
Any comment could be helpful...
I think you need to give us more information about what you are trying to do for a better answer.
The spread operator is for passing an array in place of a varargs argument, but you can't add additional arguments to the array at the same time.
If you want a new ArrayList that contains the contents of another ArrayList with an extra element added, you can do something like this:
fun main() {
val foo = arrayListOf(1, 2, 3)
val bar = arrayListOf<Int>().apply {
addAll(foo)
add(4)
}
println(foo)
println(bar)
}
Output:
[1, 2, 3]
[1, 2, 3, 4]
But it's not efficient, because it copies all the items of foo into bar.
Spread operator is not applicable to Lists, it's intended only for arrays:
fun howSum(targetSum: Int, numbers: ArrayList<Int>): IntArray? {
if (targetSum == 0) return intArrayOf()
if (targetSum < 0) return null
for (number: Int in numbers) {
val remainder = targetSum - number;
val remainderResult = howSum(remainder, numbers);
if (remainderResult != null) {
return intArrayOf(*remainderResult, number)
}
}
return null
}
If you want to create new List of the other one with addition of some element, you can use + operator:
fun howSum(targetSum: Int, numbers: ArrayList<Int>): List<Int>? {
if (targetSum == 0) return arrayListOf();
if (targetSum < 0) return null;
for (number: Int in numbers){
val remainder = targetSum - number;
val remainderResult = howSum(remainder, numbers);
if (remainderResult != null){
return remainderResult + number
}
}
return null
}

Update random class attribute in Kotlin

I have a class with some attributes:
class DonutBox {
var glaze: Int = 0
var chocolate: Int = 0
var maple: Int = 0
var etc: Int = 0
}
fun addDonuts() {
val omNom = DonutBox()
}
How can I increment a random attribute of the instantiated class?
For instance, if the randomly selected attribute is chocolate, then effectively:
omNom.chocolate += 1
Because Kotlin's properties are statically declared, and you want to use them dynamically, most of the methods to do that will involve reflection, which can get pretty messy and difficult to understand.
When you want dynamic data, it's probably better to use a map:
val donutBox = mutableMapOf(
"glaze" to 0,
"chocolate" to 0,
"maple" to 0,
"etc" to 0,
)
val randomKey = donutBox.keys.random()
donutBox[randomKey] = donutBox.getValue(randomKey) + 1
println(donutBox)
Output:
{glaze=0, chocolate=0, maple=1, etc=0}
That said, if you really want to use reflection, you can do it like this:
data class DonutBox(
var glaze: Int = 0,
var chocolate: Int = 0,
var maple: Int = 0,
var etc: Int = 0,
)
fun addDonuts() {
val omNom = DonutBox()
val randomProperty = omNom::class.declaredMemberProperties.random() as KMutableProperty1<DonutBox, Int>
val existing = randomProperty.get(omNom)
randomProperty.set(omNom, existing + 1)
println(omNom)
}
fun main() {
addDonuts()
addDonuts()
addDonuts()
}
Output:
DonutBox(glaze=0, chocolate=1, maple=0, etc=0)
DonutBox(glaze=0, chocolate=0, maple=0, etc=1)
DonutBox(glaze=0, chocolate=1, maple=0, etc=0)

Kotlin send me this error: For-loop range must have an 'iterator()' method

data class precioSuper(var producto:String, var precio: Int, val codigoDeBarras:String)
fun main(args: Array<String>) {
//Qué vende o super?
val galletas = precioSuper("galletas", 3, "0001")
val chocolate = precioSuper("chocolate", 5, "0002")
val leite = precioSuper("leite", 2, "0003")
var productos = arrayListOf<String>("galletas", "chocolate", "leite")
var totalProductos = productos.size
var codigoDeBarras2 = for(producto in totalProductos)
}
in the lane of code var codigoDeBarras2 = for(producto in totalProductos) kotlin send me this error: "For-loop range must have an 'iterator()' method"
The error is exactly in "totalProductos" "for(producto in totalProductos)"
The error is that you are assigning the for loop to a variable.
for is not an expression and can't be assigned.
Also the expression producto in totalProductos does not make sense as you treat totalProductos like a Collection but it is only an integer number.
If you want to iterate through the items of the list productos you can do it:
for (producto in productos) {
//..............
}
or
for (i in 0 until totalProductos) {
//..............
}
or
productos.forEach {
}
Assume you are trying to "extract" the producto property of productos list. Then you can try
var codigoDeBarras2 = productos.map { it.producto }

Comparator in binary search

I am not sure how to write comparator for Collectionos.binarySearch(). Can anyone help ? sample code:
List<Object> list1 = new ArrayList<>();
List<List<Object>> list2 = new ArrayList<>();
//loop starts
// adds elements into list1
list1.add(values);//values is an object containing elements like [3, John, Smith]
if (list2.size() == 0) {
list2.add(list1);//first element
} else {
if (index >= 0) {
int index = Collections.binarySearch(list2, list1, comparator);
list2.add(index, list1);//I want to add these elements in ascending order ?
}
}
//loop ends
How do I write comparator, so that elements in list 2 are added in ascending or descending order.
You can use an anonymous class which implements a Comparator<List<Object>>:
int index = Collections.binarySearch(list2, list1, new Comparator<List<Object>>() {
#Override
public int compare(List<Object> o1, List<Object> o2) {
// Your implementation here
return 0;
}
});
You could implement an IComparer<List<Object>> class, or use a lambda expression.
You just need to create a class that implements the Comparator interface.
For example, you can do this inline with an anonymous class:
Comparator<List<Object>> comparator = new Comparator<List<Object>>() {
#Override
public int compare(List<Object> x, List<Object> y) {
// custom logic to compare x and y here. Return a negative number
// if x < y, a positive number if x > y, and 0 otherwise
}
};
Collections.binarySearch(list, comparator);

CDT : Parsing enumerations, enumerators and corresponding values

I'm developing an extension of eclipse CDT plug-in which has to parse the c++ code and find all
enumerations (names)
enumerators (names)
enumerator values (numbers)
Suppose .cpp file contains following text
enum SomeEnum
{
One = 0,
Two = 1,
Three = 2,
Four = 3,
maxNum
};
The pluging should output following :
Enumeration - SomeEnum
Enumerators - One, Two, Three, Four, maxNum
Values - 0, 1, 2, 3,
The visitor method of ASTVisitor inherited class finds the enumerations this way
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTDeclSpecifier specifier = ((IASTSimpleDeclaration)declaration).getDeclSpecifier();
if (specifier instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumSpecifier = (IASTEnumerationSpecifier)specifier;
IBinding binding = enumSpecifier.getName().resolveBinding();
System.out.println(enumSpecifier.getName());
}
}
return PROCESS_CONTINUE;
}
Question : How can I iterate over the enumerators and their corresponding values of found enumeration ?
Well figured out on my own
public int visit(IASTDeclaration declaration) {
if (declaration instanceof IASTSimpleDeclaration) {
IASTDeclSpecifier specifier = ((IASTSimpleDeclaration)declaration).getDeclSpecifier();
if (specifier instanceof IASTEnumerationSpecifier) {
IASTEnumerationSpecifier enumSpecifier = (IASTEnumerationSpecifier)specifier;
// Get the current enumeration name
String enumerationName = enumSpecifier.getName().toString();
IASTEnumerator[] enumerators = enumSpecifier.getEnumerators();
for (IASTEnumerator enumerator : enumerators)
{
System.out.println(enumerator.getName());
if (enumerator.getValue() instanceof IASTLiteralExpression ) {
System.out.println(enumerator.getValue());
}
}
}
}
return PROCESS_CONTINUE;
}