kotlin "contains" doesn't work as expected - arrays

I am working with a method which filters the preferences which match with the ids, I am using the contains method, but even though the values are the same, the contains is showing a false in each iteration. The method looks like:
private fun filterPreferencesByIds(context: MyPodCastPresenterContext): List<FanPreferences> {
return context.preferences?.filter {
context.ids.contains(it.id)
}
}
The values of the arrays are:
for the context.ids:
"B52594F5-80A4-4B18-B5E2-8F7B12E92958" and "3998EDE7-F84B-4F02-8E15-65F535080100"
And for the context.preferences:
But even though, when the first and the final ids have the same id value as the context.ids, the contains is false in the debug. I think it could be related with the types in the context.ids rows Json$JsonTextNode. Because when I did the same with numeric values hardcoded the compare is successful.
Any ideas?
Thanks!

If the type of FanPreferences.id is String and the type of context.ids list element is JsonTextNode, you won't find an element equal to the given id string, because it's not of String type.
Try mapping your context ids to the list of strings before filtering:
val ids = context.ids.map { it.toString() }.toSet()
return context.preferences?.filter {
ids.contains(it.id)
}
Note that calling toString() on JsonTextNode might be not the best way to get the string data from it. It's better to consult the API documentation of that class to find it out.

Related

how to convert a string array to a boolean array in typescript

I have a list of objects that gets returned from the font end as
item=["false","true"]
i take these items to check a column from my records to see which values contain true or false as follows
this.records.filter(x=> items.includes(x.column))
but my records are always returning empty.
if i hard code it as example this.records.filter(x=> x.column == false) it works.
But i am using includes() because a user can select both true or false options and i cant go hard code it cause i wont know what the user might select.
how do i convert the string ["true","false"] into [true,false]?
i tried declaring items as
public items:boolean[]=[];
but still no luck
You can convert it using items.map(item => item === "true")

Sorting a 2 dimensional array of objects in Kotlin

I have a static 2 dimensional array of objects in a Kotlin project:
class Tables {
companion object{
lateinit var finalTable: Array<Array<Any?>?>
}
}
It is a little clearer in Java:
public class Tables {
public static Object[][] finalTable;
}
The third element in one row of objects in the table, is a string boxed as an object. In other words: finalTable[*][2] is a string describing the item. When I add an item to the array in Kotlin, I want to sort the entire array in alphabetical order of the description.
In Java this is easy:
Arrays.sort(Tables.finalTable, Comparator.comparing(o -> (String) o[2]));
When I try to use Android Studio to translate the Java code into Kotlin, it produces the following:
Arrays.sort( Tables.finalTable, Comparator.comparing( Function { o: Array<Any?>? -> o[2] as String }) )
This does not work, you have change the String cast as follows:
Arrays.sort( Tables.finalTable, Comparator.comparing( Function { o: Array<Any?>? -> o[2].toString() }) )
This version will compile and run, but it totally messes up the sorting of the table, so it does not work. I have tried variations on this theme, without any success. To get my project to work, I had to create a Java class in the Kotlin project with the functional Java code listed above:
public class ArraySort {
public void sortArray(){
Arrays.sort(Tables.finalTable, Comparator.comparing(o -> (String) o[2]));
}
}
This sorts the table like a charm, but I would prefer to keep my project "pure Kotlin". Can anyone suggest a pure Kotlin method to sort such an array? Thanks!
Unless I'm missing something, you can just do this:
Tables.finalTable.sortBy { it[2] as String }
which sorts your array in place. sortedBy will produce a new copy of the original if that's what you want instead, and might be why the comment suggestions weren't working for you.
But this whole unstructured array situation isn't ideal, the solution is brittle because it would be easy to put the wrong type in that position for a row, or have a row without enough elements, etc. Creating a data structure (e.g. a data class) would allow you to have named parameters you can refer to (making the whole thing safer and more readable) and give you type checking too

Getting null value when accessing fields from result in Searcher in Vespa

My Searcher is given below. When I hit search API then in my Searcher, I am getting null values when I tried to get fields of document. I am able to get id, relavance and source but not fields. Why is it so?Am I doing something wrong? Please help.
#Override
public Result search(Query query, Execution execution) {
// pass it down the chain to get a result
Result result = execution.search(query);
String title = result.hits().get(0).getField("title");
System.out.println(title);
// return the result up the chain
return result;
}
I am getting null value in title.
This is because results are initially surfaced without field data added (for performance).
Add
execution.fill(result);
before accessing fields (send the summary class to fill as second argument if you have multiple ones).
Use execution.fill(result) to fill the result before accessing fields. See also https://docs.vespa.ai/documentation/reference/inspecting-structured-data.html

proper way to get the last element of the array when split is used on the string within JSON

I have a JSON response from the server and I am using map to use only necessary key:valuepairs in Angular (typescript) that will be used to display on the Frontend side.
here bizStep is actually according to a standard (EPCIS) and has the following value:
urn:epcglobal:cbv:bizstep:receiving
I only want to the user to read receiving hence I used split and obtained the last value of the array to display the value.
The logic is shown below:
this.serv.getEpcisInfo(code) // HTTP GET Service from Angular
.subscribe(res => {
this.data = res.map(el => { // map only some key value pairs now!
return {
'business step': el.bizStep.split(':')[el.bizStep.split(':').length - 1]
});
});
But it is observed that in order to obtain the overall length of the splited string array I have to write the expression el.bizStep.split(':') twice.
Is there a shorthand or elegant expression to obtain the last string value of the array.
I did try to use el.bizStep.split(':')[-1] however this expression failed and did not provide me any value.
You can use Array.pop since you don't need to preserve the result of the split, i.e. el.bizStep.split(':').pop().
A more general approach would be to use an anonymous function, e.g.:
(s => s[s.length-1])(el.bizStep.split(':'))
You could modify this to get elements other than the last. Of course, this example has no error checking on the length or type of el.bizStep.

How to find which element failed comparison between arrays in Kotlin?

I'm writing automated tests for one site. There's a page with all items added to the cart. Maximum items is 58. Instead of verification of each element one by one I decided to create 2 arrays filled with strings: 1 with correct names : String and 1 with names : String I got from the site. Then I compare those 2 arrays with contentEquals.
If that comparison fails, how do I know which element exactly caused comparison fail?
Short simple of what I have now:
#Test
fun verifyNamesOfAddedItems () {
val getAllElementsNames = arrayOf(materials.text, element2.text,
element3.text...)
val correctElementsNames = arrayOf("name1", "name2", "name3"...)
val areArraysEqual = getAllElementsNames contentEquals correctElementsNames
if (!areArraysEqual) {
assert(false)
} else {
assert(true)
}
}
This test fails if 2 arrays are not the same but it doesn't show me the details, so is there a way to see more details of fail, e.g. element that failed comparison?
Thanks.
I recommend using a matcher library like Hamcrest or AssertJ in tests. They provide much better error messages for cases like this. In this case with Hamcrest it would be:
import org.hamcrest.Matchers.*
assertThat(getAllElementsNames, contains(*correctElementsNames))
// or just
assertThat(getAllElementsNames, contains("name1", "name2", "name3", ...))
There are also matcher libraries made specifically for Kotlin: https://github.com/kotlintest/kotlintest, https://yobriefca.se/expect.kt/, https://github.com/winterbe/expekt, https://github.com/MarkusAmshove/Kluent, probably more. Tests using them should be even more readable, but I haven't tried any of them. Look at their documentation and examples and pick the one you like.
You need to find the intersection between the two collections. Intersection will be the common elements. After than removing the intersection collection from the collection you want to perform the test will give you the complementary elements.
val intersection = getAllElementsNames.intersect(correctElementsNames)
getAllElementsNames.removeAll(intersection)

Resources