init function for initializing List in Kotlin - list

I am trying to give init function some extra handling using the if else conditions:
val allDates = List<String>(daysInMonth) { "0$it" if(it/10 == 0) else it.toString() })
This is not a valid syntax for the init function and there seems to be very little information on this out there.
Any suggestions on how to do this?

it looks like your if statement is wrongly formated, try this
val allDates = List<String>(daysInMonth) { if(it/10 == 0) "0$it" else it.toString() }

if you want declare first array allDates
the init for allDates like this
val daysInMonth = 30
val allDates = arrayListOf<String>()
for(i in 1..daysInMonth){
if(i/10 == 0){
allDates.add("0$i")
}else{
allDates.add("$i")
}
}

Related

How to swap elements in MutableList in Kotlin?

I have a list with data that I pull from api. However, I need to make changes on this list (movieList). I need to swap the element at index 0 with the element at index 1. For example:
list[0] = movieA,
list[1] = movieB
then
list[0] = movieB,
list[1] = movieA
The class I intend to do these operations is below:
data class MovieListDto(
val docs: List<Movie>,
val limit: Int,
val offset: Int,
val page: Int,
val pages: Int,
val total: Int
)
fun MovieListDto.MovieListDtoToMovieList(): List<Movie> {
val movieList = mutableListOf<Movie>()
for (movie in docs) {
if (movie._id == "5cd95395de30eff6ebccde5c" ||
movie._id == "5cd95395de30eff6ebccde5b" ||
movie._id == "5cd95395de30eff6ebccde5d"
) {
movieList.add(movie)
}
}
return movieList
}
How can I do this?
You could use a simple extension function for that:
fun <T> MutableList<T>.swap(index1: Int, index2: Int){
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp
}
it can be use like this:
list.swap(0, 1)
val temp = movieList[0]
movieList[0] = movieList[1]
movieList[1] = temp
I think you can use also scope function to swap
movieList[0] = movieList[1].also { movieList[1] = movieList[0] }
use Collections.swap() method in JDK
see https://developer.android.com/reference/java/util/Collections#swap(java.util.List%3C?%3E,%20int,%20int)

Scala function takes 2 hours with 2 million values

Would be grateful if any ideas to speed it up!
case class Pair(aa:String, bb:String)
case class OutputRow(bb:String, aa:String, bb_2:String, aa_2:String)
def startSearch(
_1_sorted: Array[Pair] ,
_2_hashmap: HashMap[String, String] ) : ArrayBuffer[OutputRow] = {
var outputTableListBuffer = ArrayBuffer[OutputRow]()
var searchComparisionFlag = false
var storeMain = Pair("0","0") //Initialize with Dummy data
var i = 0
def search(xxxx_1: Pair): Unit = {
if (searchComparisionFlag==true) {
var _2_exists = _2_hashmap.exists(_._1 == xxxx_1.aa)
if (_2_exists) {
val _2_xxxx = _2_hashmap(xxxx_1.aa)
outputTableListBuffer.append(OutputRow(storeMain.aa, storeMain.bb,_2_xxxx, xxxx_1.aa))
i = i + 1
if (i % 1000 == 0) println("In recursive search storeMain: ", storeMain)
var storePair = Pair(_2_xxxx,xxxx_1.aa)
search(storePair)
} else {
searchComparisionFlag = false
return
}
} else {
var _2_exists = _2_hashmap.exists(_._1 == xxxx_1.aa)
if (_2_exists) {
val _2_xxxx = _2_hashmap(xxxx_1.aa)
searchComparisionFlag = true
outputTableListBuffer.append(OutputRow(xxxx_1.aa, xxxx_1.bb,_2_xxxx, xxxx_1.aa))
var store = Pair(_2_xxxx,xxxx_1.aa)
search(store)
}
}
}
_1_sorted.foreach{ aa_1 =>
val store = Pair(aa_1.aa, aa_1.bb)
storeMain = store
search(store)
}
outputTableListBuffer
}
The above function takes 2 hours with 1 million values in _1_sorted and with a good 1 Million lookup in the hashmap.
Any ideas to speed this up?
This is a recursive logic function
The biggest problem is this:
_2_hashmap.exists(_._1 == xxxx_1.aa)
This is checking every single element of the hashmap on every call. Instead, use get:
_2_hashmap.get(xxxx_1.aa) match {
Some(_2_xxxx) => // Found
???
None => // Not found
???
}
Other code issues:
Don't use return
Pass flags down through recursive call rather than using global var
Use val wherever possible
Don't start variable names with _

Find if an element with a specific property value is found in a list

I'm trying to find a value in a list of objects in kotlin, using for it "filter", but I need to return true or false if the value is found, but filter returns me a list of object in the case of match.
t.filter { it.retailerId == value }
¿How I can return a boolean when I find this value in the list of objects?
If you need that the element is exactly one:
t.filter { it.retailerId == value }.size == 1
if not:
t.any { it.retailerId == value }
With foldRight and a break when you found it:
t.foldRight(false) {val, res ->
if(it.retailerId == value) {
return#foldRight true
} else {
res
}
}
In alternative to firstOrNull you can also use any with the same predicate:
val found = t.any { it.retailerId == value }
You can use firstOrNull() with the specific predicate:
val found = t.firstOrNull { it.retailerId == value } != null
If firstOrNull() does not return null this means that the value is found.
For single element
list.first { it.type == 2 (eg: conditions) }
or
list.firstOrNull { it.type == 2 (eg: conditions) }
For list of elements
list.filter { it.type == 2 (eg: conditions) }
Kotlin has this nice extension function which u can use
if (none { it.isSelected == true }) {
first().isSelected = true
}

Googlescript 'if' question - do only one of two tasks

I have 'else if' statements and I need it to be called only if the previous 'if' does not execute. First 'if' (check status) work perfect, second work to, but the 'else if' is done every time because there are different types in the table (A, B, C e.t.c)
Edit:
1. New line must be add if there's no open A;
2. If there are open more than one A - all are must be closed;
3. Ignore all other types and add new line only if there are no As open;
Here is my code:
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SheetName');
var data = sheet.getRange(2,1,sheet.getLastRow(),2).getValues();
var nextRow = SpreadsheetApp.getActiveSheet().getDataRange().getLastRow()+1;
for (var i=0; i<data.length; i++){
var row = data[i];
var type = row[0];
var status = row[1];
//check it always
if (status != 'close'){
//check first and if it's true don't do 'else if'
if (type == 'A') {
sheet.getRange(i+2,2).setValue('close')
}
//this should only be called if the previous 'if' is not true
else if (type != 'A' && type != ''){
var values = [['A','open']];
sheet.getRange("A"+nextRow+":B"+nextRow).setValues(values);
}
}
}
}
Flow:
Loop through all data to find if there's a "A:Open"
If found in all of data, just close that row
else, Add a new line: "A:Open"
Use a Boolean variable(isThereASingleAOpen) to keep track of A:Open found status
Sample script:
function closeAandAddOpenA() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SheetName');
//Separate range and data
var range = sheet.getRange(2, 1, sheet.getLastRow(), 2);
var data = range.getValues();
//Is there a A Open in the data? Let's assume there's none
var isThereASingleAOpen = false;
//Loop through data array
for (var i = 0; i < data.length; i++) {
var row = data[i];
var type = row[0];
var status = row[1];
//If status is != close and type == 'A'
if (status != 'close' && type == 'A') {
//Change current row status to close in the data array
row[1] = 'close';
//Oops We were wrong. There was a A open in the data
isThereASingleAOpen = true;
}
} //Loop closed
//Set the modified data back to the range
//Batch operations are faster
range.setValues(data);
//if there is NOT a single A open in all of data, Append a new line
if (!isThereASingleAOpen) {
sheet.appendRow(['A', 'Open']);
}
}

Why wont this IF statement work in Unity?

Okay I have a problem. I am using an IF statement. It seems to not run like it should. It works fine without the || condition, but with the || it seems to just pull the text under and not run the ELSE...
var fateText : UI.Text;
var inputText : UI.Text;
function fateBall () {
if(inputText.text == "illuminati"||"Illuminati"){
fateText.text = "We run the entire world. Join us!";
}else{
var myRandomString : String = RandomWordString(1);
fateText.text = myRandomString;
}
}
If i remove the ||"Illuminati" it works great... but like this it assigns fateText.text to "We run the entire world." and not the myRandomString
EDIT REPORT: Okay, the .ToLower() worked great now I am running into a problem where when I add multiple IFs it just bypasses the IFs and just runs the ELSE... any ideas?
function fateBall () {
if(inputText.text.ToLower() == "illuminati"){
fateText.text = "We run the entire world. Join us!";}
if(inputText.text.ToLower() == "satan"){
fateText.text = "Lucifer is the Light Bringer. He leads us against God!";}
if(inputText.text.ToLower() == "devil"){
fateText.text = "Lucifer is the Light Bringer. He leads us against God!";}
if(inputText.text.ToLower() == "lucifer"){
fateText.text = "Lucifer is the Light Bringer. He leads us against God!";}
else{
var myRandomString : String = RandomWordString(1);
fateText.text = myRandomString;
}
}
The condition must be :
if(inputText.text == "illuminati" || inputText.text == "Illuminati")
Otherwise, you can set to lower all the text so as to be case-independant :
if(inputText.text.ToLower() == "illuminati")
An even better way to compare strings is to use the Equals function (C# only though)
if( String.Equals( inputText.text, "illuminati", System.StringComparison.InvariantCultureIgnoreCase)
EDIT further to your EDIT:
string lowerText = inputText.text.ToLower() ;
if(lowerText == "illuminati")
{
fateText.text = "We run the entire world. Join us!";
}
else if(lowerText == "satan")
{
fateText.text = "Lucifer is the Light Bringer. He leads us against God!";
}
else if(lowerText == "devil")
{
fateText.text = "Lucifer is the Light Bringer. He leads us against God!";
}
else if(lowerText == "lucifer")
{
fateText.text = "Lucifer is the Light Bringer. He leads us against God!";
}
else
{
var myRandomString : String = RandomWordString(1);
fateText.text = myRandomString;
}
Try changing the condition from:
inputText.text == "illuminati"||"Illuminati"
To this:
inputText.text == "illuminati"|| inputText.text =="Illuminati"
I don't think you can chain conditions like that.
In addition you may want to just use a lowercase function to simplify your condition. So I believe you can do the following instead.
if(inputText.text.ToLower()=="illuminati")
If you want to check multiple condidtions in one if statement do it like this:
if (var1 == condition1 || var2 == condition2){}
this will check if either one return true, but you can also check if multiple statements are true by using:
if (var1 == condition1 && var2 == condition2){}