does `minBy` actually give a reference to original...
# announcements
w
does
minBy
actually give a reference to original object? I do
lowest = lowest?.next
in my code above, does it actually move the
head
of the list stored in
lists
?
d
Objects work by references, you are never actually working on the object, only a reference to it.
w
Okay so its like pointers in c++? If I manipulate
lowest
here it will change in the original array too?
d
No, it's not like pointers.
Copy code
val x = MyObject() // x holds reference to that object
val y = x // y is set to the same value as x, i.e. the reference to the object
Everything is pass-by-value, but you are not passing objects, you are passing references.
w
going with your example,
val x = 9; var y = x; y = 8
obviously x doesn't become 8
d
Yes.
Everything is pass-by-value
w
okay yeah that makes sense i was just wondering how this LL works in such a scenario:
Copy code
class ListNode(var `val`: Int = 0) {
        var next: ListNode? = null
    }
d
What do you mean by LL?
w
linkedlist* sorry
Copy code
var head: ListNode?
        head = head?.next
I guess this works because
head
is simply being overwritten?
d
You are storing a new value in
head
, yes. I am not sure why you think this would not work?
w
yeah sorry i was just confused i guess
` var lowest = lists.minBy { it?.
val
?: Int.MAX_VALUE } `
Copy code
var lowest = lists.minBy {  it?.`val` ?: Int.MAX_VALUE }
Copy code
lowest = lowest?.next
this is what im trying to do
but of course the original list stored in
lists
isn't affected by
lowest = lowest?.next
d
No, of course not.
w
whats a good kotlin-y way to to do this in your opinion?
d
Depends on your exactl use-case, really. What is your end goal?
w
so we have a list of single linked lists
the goal is to find the linked list with the smallest current HEAD value and then advance the head of said list to point to head.next
makes sense?
d
You are representing your "linked list" by just a pointer to the head, which is a bit bad, since thereby your linked list does not really have an identity. You would have to get the index of the linked list with the lowest value and then update that index of the main list.
For that you can do
val (lowest, lowestIndex) = lists.withIndex().minBy { (value, index) -> value.whatever }
And then
lists[lowestIndex] = lists[lowestIndex].next
But a much simpler and cleaner approach would be to write a
class LinkedList(var head: Node?)
Then you could do
Copy code
val listWithLowest = lists.minBy { it.head?.val ?: Int.MAX_VALUE }
if (listWithLowest != null) listWithLowest.head = listWithLowest.head?.next
w
interesting
val (lowest, lowestIndex) = lists.withIndex().minBy { (value, index) -> value.whatever }
whats happening in this line?
the docs for
withIndex
say 'Returns a lazy Iterable of IndexedValue for each element of the original array.'
does it return some special version of List? I mean minBy still works on it
d
list.withIndex()
turns a
List<T>
into a
Iterable<IndexedValue<T>>
. The
(value, index)
is a destructuring operation, grabbing the actual value and it's index in the list out of the
IndexedValue
.
w
or is it some special collection with index too?
d
Yes.
w
alright. so minBy works on Iterable<IndexedValue<T>> too?
d
Yes,
minBy
is defined for
Iterable
.
w
Got it
Copy code
val (lowest, lowestIndex) = lists.withIndex().minBy { (value, index) -> value.`val` ?: Int.MAX_VALUE }
apparently not nullable values are needed to destructure
so i guess il need to check for nullness first then destructure it
d
Oh, right...
minBy
is nullable. Yes
w
also, it says
val
is not defined for
value
d
Yeah, it's
(index, value)
, sorry.
You can also do
minBy { it.value.val ?: Int.MAX_VALUE }
, if you don't like the destructuring.
w
got it!