Variable interator in for cycle - kotlin

This is my example
for (i in array.indices)
{
if (array[i] == 10)
{
i -= 2//have error here
}
}
How can i make 'i' variable mutable?

You can't. Use while loop instead:
var i = 0
while (i < array.size) {
if (array[i] == 10) {
i -= 2
}
...
i++
}

Related

find and remove element from array (solidity)

I've tackled a task: find a specific address in a sheet, move it to the end of the sheet, and remove it via a function pop! here is the code:
function removeAccount(address _account) external{
uint counter = arrayOfAccounts.length;
uint index;
for(uint i; i < counter; i++) {
if(arrayOfAccounts[i] == _account){
index = i;
break;
}
for(uint i = index; i < counter-1; i++){
arrayOfAccounts[i] = arrayOfAccounts[i + 1];
}
arrayOfAccounts.pop();
}
}
}
}
transact to Wote.removeAccount errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
In case you dont care about addresses order
function removeAccount(address _account) external {
if(arrayOfAccounts.length == 1) {
arrayOfAccounts.pop();
}
else if(arrayOfAccounts[arrayOfAccounts.length - 1] == _account) {
arrayOfAccounts.pop();
}
else {
for (uint i = 0; i < arrayOfAccounts.length - 1; i++) {
if(_account == arrayOfAccounts[i]) {
arrayOfAccounts[i] = arrayOfAccounts[arrayOfAccounts.length - 1];
arrayOfAccounts.pop();
}
}
}
}
If order matters
function removeAccount(address _account) external{
uint counter = arrayOfAccounts.length;
for(uint i; i < counter; i++) {
if(arrayOfAccounts[i] == _account){
for(uint j = i; j < counter-1; j++){
arrayOfAccounts[j] = arrayOfAccounts[j + 1];
}
arrayOfAccounts.pop();
break;
}
}
}
}
Else if order doesn't matter
function removeAccount(address _account) external{
uint numAccounts = arrayOfAccounts.length;
for(uint i = 0; i < numAccounts; i++) {
if(arrayOfAccounts[i] == _account){ // if _account is in the array
arrayOfAccounts[i] = arrayOfAccounts[numAccounts - 1]; // move the last account to _account's index
arrayOfAccounts.pop(); // remove the last account
break;
}
}
}
The reason is just simple.
You used the second for loop inside the first for loop.
And also please initialize the index with counter;
uint256 index = counter;
And pop only when index is less than counter

How to write test cases using Equivalence Class, Boundary value, and Basis Path Testing

I have a method isPerfect(x) (with 4<=x<=10000) below, how to write test cases based on Equivalence Class, Boundary Value, and Basis Path Testing:
public boolean checkPerfectNumber(int x) {
if(x >= 4 && x <= 10000) {
int sum = 0;
for(int i = 1; i < x; i++) {
if(x % i == 0) {
sum += i;
}
}
if(sum == x) return true;
}
return false;
}

Calculating size of Google Firestore documents

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.
Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?
Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size
function calcFirestoreDocSize(collectionName, docId, docObject) {
let docNameSize = encodedLength(collectionName) + 1 + 16
let docIdType = typeof(docId)
if(docIdType === 'string') {
docNameSize += encodedLength(docId) + 1
} else {
docNameSize += 8
}
let docSize = docNameSize + calcObjSize(docObject)
return docSize
}
function encodedLength(str) {
var len = str.length;
for (let i = str.length - 1; i >= 0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
len++;
} else if (code > 0x7ff && code <= 0xffff) {
len += 2;
} if (code >= 0xDC00 && code <= 0xDFFF) {
i--;
}
}
return len;
}
function calcObjSize(obj) {
let key;
let size = 0;
let type = typeof obj;
if(!obj) {
return 1
} else if(type === 'number') {
return 8
} else if(type === 'string') {
return encodedLength(obj) + 1
} else if(type === 'boolean') {
return 1
} else if (obj instanceof Date) {
return 8
} else if(obj instanceof Array) {
for(let i = 0; i < obj.length; i++) {
size += calcObjSize(obj[i])
}
return size
} else if(type === 'object') {
for(key of Object.keys(obj)) {
size += encodedLength(key) + 1
size += calcObjSize(obj[key])
}
return size += 32
}
}
In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:
https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.

How to make multiconditional for loop in kotlin

In Java:
for(int j = 0; j < 6 && j < ((int)abc[j] & 0xff); j++) {
// ...
}
How we can make this loop in Kotlin?
I'd suggest to use a more functional approach like
(0..5).takeWhile {
it < (abc[it].toInt() and 0xff) // or `as Int` if array is not numeric
}.forEach {
// do something with `it`
}
If you don't mind creating a new ArrayList instance, it can be done like this:
(0..5).takeWhile { it < (abc[it] as Int and 0xff) }
.forEach {
// ...
}
Note: the .takeWhile { ... }.forEach { ... } approach suggested in some answers is not equivalent to the Java for loop. The range is first processed with .takeWhile { ... } and only then the prefix it returned is iterated over. The problem is that the execution of the .forEach { ... } body won't affect the condition of .takeWhile { ... }, which has already finished execution by the time the body gets called on the first item.
(see this runnable demo that shows how the behavior is different)
To fix this, you can use Sequence<T>. In constrast with eager evaluation over Iterable<T>, it won't process the whole set of items with .takeWhile { ... } and will only check them one by one when .forEach { ... } is up to process a next item. See: the difference between Iterable<T> and Sequence<T>.
To use the Sequence<T> and achieve the behavior that is equivalent to the Java loop, convert the range .toSequence():
(0..5).asSequence()
.takeWhile { it < (abc[it].toInt() and 0xff) }
.forEach {
// Use `it` instead of `j`
}
Alternatively, just use the while loop:
var j = 0
while (j < 6 && j < (abc[j] as Int and 0xff)) {
// do something
j++
}
This is how the kotlin version will look like.
var j = 0
while (j < 6 && j < (abc[j] as Int and 0xff)) {
// do something
j++
}
You can convert Java to Kotlin online here. Try Kotlin. Also if you are using IntelliJ, here is a link to help you convert from Java to Kotlin. IntelliJ Java to Kotlin.
I would move the j < ((int)abc[j] & 0xff) part into an if-test inside the loop. You could then do this:
for (j in 0..5) {
if (j < (abc[j].toInt() and 0xff)) {
// Do stuff here
} else break
}
This is the output of the intellij plugin for conversion:
var j = 0
while (j < 6 && j < abc[j] as Int and 0xff) {
j++
// ...
}

Getting indexOutOfBoundsException and I don't know why

I have been having this problem for a few hours. I don't know what it is, but I am having a hard time thinking clearly at the moment. This method displays a set of images. The first part of the method is just setting the gridbag constraints, whereas the next part in the if statement is creating jlabels and adding them to an arraylist of jlabels. The exception is being thrown when I try and add mouselisteners to the jlabels after they have been added to the arraylist (this is on line 112, and i have commented this on the code).
public void displayComplexStimulus(BufferedImage[] complexStimulus){
for(int i = 0; i < numberOfElements; i++){
if (i == 0 || i == 1 || i == 2){
c.gridx = i;
c.gridy = 0;
}
else if(i == 3 || i == 4 || i == 5){
c.gridx = i - 3;
c.gridy = 1;
}
else {
c.gridx = i - 6;
c.gridy = 2;
}
if(counter == 1){
if (phase1Trial.getPositionOfCorrectImage()!= i){
phase1IncorrectLabels.add(new JLabel(new ImageIcon(complexStimulus[i])));
phase1IncorrectLabels.get(i).addMouseListener(this); //line 112
add(phase1IncorrectLabels.get(i),c);
}
else if(phase1Trial.getPositionOfCorrectImage() == i){
correctLabel = new JLabel(new ImageIcon(complexStimulus[i]));
add(correctLabel, c);
correctLabel.addMouseListener(this);
}
}
}
}
If i==phase1Trial.getPositionOfCorrectImage() you're not adding an element to phase1IncorrectLabels. So in the next iteration after adding one element to the array it's at position i-1 and not i. You should replace your get(i) by get(phase1IncorrectLabels.size() - 1).