I want to get the Index of the ListA with the name test in this list
First class
class ListA {
String name;
ListA({this.name});
}
Second class
List<ListA> abc = [
ListA(name: 'test'),
];
after that, i got a statless Wiget with a button,
that is the onPressed-method
onPressed: () {
i = abc.indexOf(ListA(name: 'test'));
print(i);
},
I couldn´t find any misstakes, but unfortunately it´s always returning -1, what means it couldn´t find it
What am i doing wrong ?
This happens because you're creating a new ListA when calling indexOf, and that means you have two different ListAs. This is similar to doing:
print(ListA(name: 'test') == ListA(name: 'test'));
This will print false because they're not the same object.
You could try one of the following:
Keep a reference to the first ListA you use, and call indexOf passing the same reference in
Use const instances of ListA (mark the name field as final, add const to the constructor definition and the calls to it)
Override the == operator and hashCode on your ListA class, so that the two different instances of ListA are considered the same if their fields/items are the same
Instead of indexOf, use indexWhere and check the name (indexWhere((l) => l.name == 'test'))
Related
I'm practicing leetcode problems to perfect my kotlin syntax and am wondering why this code doesn't work. My question specifically is why doesn't my courses hashmap populate with this code.
Prerequisites is an array in this form [[0,1][0,3][4,5][6,7]] and if I print my variables for pre and post they print what I expect
But I'm trying to turn courses into an adjacency matrix like this {0: [1,3], 4: [5], 6: [7]}
and instead it just prints an empty set every time
class Solution {
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
val courses = HashMap<Int, MutableList<Int>>().withDefault{ mutableListOf<Int>() }
for ((pre, post) in prerequisites){
courses[pre]?.add(post)
}
print(courses)
return false
}
}
stdout: {}
[] does not give you the default value
From the docs of withDefault:
This implicit default value is used when the original map doesn't contain a value for the key specified and a value is obtained with Map.getValue function
If you want to get the default value, you need to use getValue instead of the index operator.
Using the index operator, you would just get null and because of the the null-safe operator, the add operation would not even be executed.
If you take a look at the relevant source code, you can see that the funxtionality get is not changed when using .withDefault but only getOrImplicitDefault returns the default value.
Getting the default does not set anything
Furthermore, when accessing courses.getValue(pre) in the loop, the Map will be empty. Because of the withDefault, it will return a MutableList where you can add elements but getting such a list and adding elements to it will not add the list to the Map. Reading and accessing an element does not insert it.
Simple solution
If you want to make sure the element is present in the Map, you can use courses[pre]=course.getValue(pre) before reading courses[pre]?:
class Solution {
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
val courses = HashMap<Int, MutableList<Int>>().withDefault{ mutableListOf<Int>() }
for ((pre, post) in prerequisites){
courses[pre] = courses.getValue(pre)
courses[pre]?.add(post)
}
print(courses)
return false
}
}
If the entry is set already, it will be set to itself (no change) and if it isn't set, it will be set to the default value (empty list).
dan1st's answer covers it - your default list is just returned, not put and returned, so it's not part of the map - but here's a different take to get that functionality:
val courses = HashMap<Int, MutableList<Int>>().run {
withDefault{ key ->
mutableListOf<Int>().also { put(key, it) }
}
}
So basically using the withDefault wrapper, using run so the map is this in the default value function, so you can add your list to the map before returning it. Then when you call courses.getValue(69) you'll get back a list that's already been inserted into the map
If you like, there's also a function that'll do this grouping for you, groupBy
val nums = arrayOf(
intArrayOf(0,1),
intArrayOf(0,3),
intArrayOf(4,5),
intArrayOf(6,7)
)
val groups = nums.groupBy(keySelector = { it[0] }, valueTransform = { it[1] })
println(groups)
>> {0=[1, 3], 4=[5], 6=[7]}
I have a class in my model that includes a list of bool. From my UI I want to set the bool state in just a single item in the list via a setter (so that I can also save it). I can't figure out the syntax (or whether this is a valid thing to do).
///This is OK
set notificationDismissed(bool notificationDismissed){
_notificationDismissed = notificationDismissed;
saveParameterBoolean(_notificationDismissedKey,
_notificationDismissed);
}
bool get notificationDismissed => _notificationDismissed;
///This is OK too
List<bool> get questionsAnswered => _questionsAnswered;
set questionsAnswered(List<bool> questionsAnswered){
_questionsAnswered = questionsAnswered;
for(int i=0; i<_questionAnsweredParamKeys.length; i++ ){
saveParameterBoolean(_questionAnsweredParamKeys[i],
_questionsAnswered[i]);
}
updateState();
}
///This is not OK !!!! but should show what I want to do
List<bool> get questionsAnswered[index] => _questionsAnswered[index];
set questionsAnswered[index](bool questionsAnswered[index]){
_questionsAnswered[index] = questionsAnswered[index];
saveParameterBoolean(_questionAnsweredParamKeys[index],
_questionsAnswered[index]);
updateState();
}
I know I'm missing something obvious here, any help greatly appreciated
get and set functions can't take any arguments. The simplest approach would be to use normal functions:
bool getQuestionsAnswered(int index) => _questionsAnswered[index];
void setQuestionsAnswered(int index, bool value) {
_questionsAnswered[index] = value;
saveParameterBoolean(_questionAnsweredParamKeys[index], _questionsAnswered[index]);
updateState();
}
Another alternative would be to change _questionsAnswered from a List to a custom class that implements operator [] (to get an element) and operator []= (to set an element), and then you could make them do whatever you want.
Please tell me why I cannot add these elements into the List. Please find the attached screenshot for the error.
public class PracticeOnLists {
List<String> myList = new List<String>();
myList.add('element1');
myList.add('element2');
myList.add('element3');
myList.add('element4');
System.debug('The List is' + myList);
System.debug('The size o the List is ' + myList.size());
}
There are major problems in your code.
List is an interface, so you cannot create objects of an interface. You'll have to create an object from a child class of List.
In Java you need double quotes(") to create a String.
And you cannot write statements just inside a class. They must be in a method or a block.
If you want to get viewable outputs I suggest you use System.out.println() since there's no method called debug() in the System class.
So this should be your code
List<String> myList = new ArrayList<String>();
void addToList() {
myList.add("element1");
myList.add("element2");
myList.add("element3");
myList.add("element4");
System.out.println("The List is" + myList);
System.out.println("The size o the List is " + myList.size());
}
The problem is that you have to do this inside a method. Single quotes are correct-double quotes are wrong in Apex(Salesforce) NOT Java.
public void doItHere() {
myList.add('element1');
myList.add('element2');
myList.add('element3');
myList.add('element4');
}
import groovy.transform.EqualsAndHashCode;
#EqualsAndHashCode(includes="name")
class Activity {
public String name
public buildings = []
public rooms = [] as Set
Activity(name) {
this.name = name
}
}
thisActivity=new Activity("activity")
activityRegistry = []
// is false correct
activityRegistry.contains(thisActivity)
// add new item activity2
activityRegistry << new Activity("activity2")
// is true?????
activityRegistry.contains(thisActivity)
this code is pretty straight forward, I create an activityRegistry list, I compare empty list to object I created. naturally test fails. I create a new object on the fly using new that I insert into the list. I compare the list then to the first object created, which is not part of the list, and contains, or in passes. could someone shed some light on how? or why?
The AST "EqualsAndHashCode" only use 'properties' from the class. Properties, in groovy, are declared without a modifier ('public'), and getter/setter are automatically generated.
In your example, change public String name to String name.
See : What are 'properties' in Groovy?
I'm sure there is a way to do this, but I'm really stuck on this one.
I have a domain model that connects to entities Foo and Bar in a many-to-many-relationship. Now when I want to list all Foos to a certain Bar, I do the query and get a lot of FooBar objects. I iterate through these objects and add all Foos to a list.
Like so:
def fooBarRelations = FooBar.findAllByBar bar
def fooList = []
fooBarRelations.each { fooList.add it.foo }
How can I sort the fooList based upon the parameters a g:sortableColumn adds to the url namely sort (the field to sort) and order.
I know you can pass the parameters to the query directly but I think this is not possible in my case?
So how can I either
Make one query without list iterating so I can pass in the sorting parameters OR
Sort my custom list based upon the sorting parameters?
Addition 1 (03/25/2012)
If I could to this ...
def fooBarRelations = FooBar.findAllByBar bar, [sort: 'foo.' + params.sort, order: params.order]
... the problem would be solved. But passing this to the query does not have any effect on the output. Is there any way I can sort a query by a sub-property?
If you really can't sort within the query itself. Then you need a list of lists.
List<List<Fields>> mylist;// where List<Fields> is a lists of the fields.
Then use a Comparator to sort your List> by the desired filed. Say your desired field is at index 3:
new Compare(List<Fields> L1, List<Fields> L2){
if(L1.get(3)>L2.get(3))
return -1;//etc.
UPATE BASED ON COMMENT:
say your entity is as follows
public class Entity{
String name, address, school;
Integer bankaccount;
//etc...
}
Then
public class WhereISort{
List<Entity> myList;
String mysorter;//mysorter can be declared here as static final
public WhereISort(){//maybe pass list in here or whatever
}
public Response myWebService(params..., String sorter){
mysorter=sorter;//mysorter can be declared here as static final
Collections.sort(myList, new Comparator() {
public int compare(Entity e1, Entity e2) {
if(mysorter.equalsIgnoreCase("name")){
return e1.getName().compareToIgnoreCase(e1.getName());
}else if(mysorter.equalsIgnoreCase("bankaccount")){
//your code here, etc.
}
}
});
}
}
Of course, the main point is using "mysorter" and the inner class "Comparator" to sort