I recently realised there are two very similar functions in Kotlin for getting a portion of a List, but I'm unsure of the difference:
The documentation for List.subList says:
Returns a view of the portion of this list between the specified fromIndex (inclusive) and toIndex (exclusive). The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.
Structural changes in the base list make the behavior of the view undefined.
whereas the documentation for slice says:
Returns a list containing elements at indices in the specified indices range.
Or
Returns a list containing elements at specified indices.
It seems that the key differences are that the first one returns a "view of the portion" of the list, and whether non-structural changes are reflected? However I'm not quite sure what this means.
I looked at the source code for the slice function:
public fun <T> List<T>.slice(indices: IntRange): List<T> {
if (indices.isEmpty()) return listOf()
return this.subList(indices.start, indices.endInclusive + 1).toList()
}
But it returns a list from the subList function.
Could someone explain the differences between these two functions and when you might want to use one over the other?
The key in List<T>.slice function is the .toList() at the end.
The call to toList() will create a new List with all the elements, like a copy.
For summary:
.slice() will create a new List with the subset of elements
.subList() is only a view of the original List that will change with it.
You can see differences here: https://pl.kotl.in/-JU8BDNZN
fun main() {
val myList = mutableListOf(1, 2, 3, 4)
val subList = myList.subList(1, 3)
val sliceList = myList.slice(1..2)
println(subList) // [2, 3]
println(sliceList) // [2, 3]
myList[1] = 5
println(subList) // [5, 3]
println(sliceList) // [2, 3]
}
Related
In OCaml, suppose I have a string list as follows:
let ls : string list = ["A"; "A"; "B"; "B"; "A"; "Y"; "Y"; "Y"] ;;
I'm having trouble writing a function that calculates how many times an element occurs consecutively and also pairs up that element with its frequency. For instance, given the above list as input, the function should return [("A", 2); ("B", 2), ("A", 1), ("Y", 3)].
I've tried looking for some hints elsewhere but almost all other similar operations are done using int lists, where it is easy to simply add numbers up. But here, we cannot add strings.
My intuition was to use something like fold_left in some similar fashion as below:
let lis : int list = [1;2;3;4;5]
let count (lis : int list) = List.fold_left (fun x y -> x + y) (0) (lis)
which is essentially summing all the elements cumulatively from left to right. But, in my case, I don't want to cumulatively sum all the elements, I just need to count how many times an element occurs consecutively. Some advice would be appreciated!
This is obviously a homework assignment, so I will just give a couple of hints.
When you get your code working, it won't be adding strings (or any other type) together. It will be adding ints together. So you might want to look back at those examples on the net again :-)
You can definitely use fold_left to get an answer. First, note that the resultl is a list of pairs. The first element of each pair can be any type, depending on the type of the original list. The second element in each pair is an int. So you have a basic type that you're working with: ('a * int) list.
Imagine that you have a way to "increment" such a list:
let increment (list: ('a * int) list) value =
(* This is one way to think of your problem *)
This function looks for the pair in the list whose first element is equal to value. If it finds it, it returns a new list where the associated int is one larger than before. If it doesn't find it, it returns a new list with an extra element (value, 1).
This is the basic operation you want to fold over your list, rather than the + operation of your example code.
I am trying to implement a recursive Prolog predicate that when given a all 0 list ResultList with Dim elements and another list with values up to Dim, it runs trough this second list and increments +1 to the nth Element of ResultList and returns ResultList, so far I have:
increment_list([],_).
increment_list([Element|Tail],ResultList):-
nth1(Element,ResultList,_ is _+1),
increment_list(Tail,ResultList).
So for example
?-increment_list([1,2,4,3,4],[0,0,0,0]).
Would return:
[1,1,1,2]
What I'm apparently having difficulty and confusion is how to increment the value, is it possible to do it without defining an extra predicate or having a singleton Variable?
In prolog you cannot modify the value inside a list. You can do something like this:
increment_list([],L,L).
increment_list([H|T],LT,LO):-
increment_nth(H,1,LT,LT1),
increment_list(T,LT1,LO).
increment_nth(_,_,[],[]).
increment_nth(I,I,[H1|T1],[H2|T1]):-!,
succ(H1,H2).
increment_nth(I,C,[H|T1],[H|T2]):-
C1 is C+1,
increment_nth(I,C1,T1,T2).
Is basically a nested loop. In each loop you create a new list, which is the same previous list except the value at the index you consider which is the previous index incremented by one.
?- increment_list([1,2,4,3,4,1],[0,0,0,0],LO).
LO = [2, 1, 1, 2]
EDIT
Thanks to Daniel Lyons, i've modified the predicate.
this might not be the best question but I am curious about what might be going on.
I have this piece of code in groovy
def markets = []
for (int i = 0; i < marketIds.size(); i += 200) {
int from = i
int to = (i + 200) > marketIds.size() ? marketIds.size() : (i + 200)
markets.addAll(service.getMarketCatalog(args...))
}
markets
service.getMarketCatalog() returns a list of objects/maps (it's a call to 3rd part API that returns a list of some objects defined in their API. We get them as maps).
For some reason the result of this method is markets being a list of lists.
So if the for loop runs 3 times and the API responds each time with a list, the list is added to the markets as an object.
Anyone have any ideas why? Maybe I have to define that the result is a list (i.e. service.getMarketCatalog(args...) as List) otherwise it is treated as an object and just gets added as an object to the list?
Judging by my own test...
Object x() { return [1, 2] }
def y = []
y.addAll(x())
y.addAll(x())
println y
Result: [1, 2, 1, 2]
... no matter what the return type of service.getMarketCatalog() is, even if it's just Object, if the value is truly a List or other Collection, then addAll has the expected behavior. I get a warning in the IDE, but Groovy evidently tries casting the Object to a Collection at runtime and succeeds.
Thus I can only conclude that service.getMarketCatalog() is not actually returning a single-level list as you believe it is. It must be a list of lists, itself. You'll have to investigate whether that's truly the case. If it is, then of course you can spread the top-level list to addAll each of the sublists: markets.addAll(*service.getMarketCatalog(args...))
I want to return the first element of the list each time the user requests for another value i.e. List = [1, 2, 3], when the program is executed it returns 1, however, when ; is pressed (user asks for another value) then 2 is returned and so on, till the list is empty.
Though I have managed to list all values at once, but the key question here is that, how can I wait and let the user decide of he wants another value or not.
Just do this:
member( X, List ).
This will enumerate the next member of List on each ;. Each call to the predicate will instantiate the next member of List in X until all of the members are exhausted.
yes there is a built-in function that does that, but I think you should try to write it yourself to better understand Prolog.
each_one([A|_],A).
one of the elements of a list is its head element.
each_one([_|B],X):- each_one(B,X).
more elements are in the list's tail. This is the recursive clause.
There are no elements in the empty list, so we don't write anything (though we could write each_one([],_):- fail. with the same effect).
Now you can try it:
4 ?- each_one([1,2,3],X).
X = 1
Prolog shows you the first solution and waits for your response. You press ';' to continue:
;
X = 2 ;
X = 3 ;
false.
Question is simple.
How to access a tuple by using Index variable in SML?
val index = 5;
val tuple1 = (1,2,3,4,5,6,7,8,9,10);
val correctValue = #index tuple1 ??
I hope, somebody would be able to help out.
Thanks in advance!
There doesn't exist a function which takes an integer value and a tuple, and extracts that element from the tuple. There are of course the #1, #2, ... functions, but these do not take an integer argument. That is, the name of the "function" is #5, it is not the function # applied to the value 5. As such, you cannot substitute the name index instead of the 5.
If you don't know in advance at which place in the tuple the element you want will be at, you're probably using them in a way they're not intended to be used.
You might want a list of values, for which the 'a list type is more natural. You can then access the nth element using List.nth.
To clarify a bit, why you can't do that you need some more knowledge of what a tuple is in SML.
Tuples are actually represented as records in SML. Remember that records has the form {id = expr, id = expr, ..., id = expr} where each identifier is a label.
The difference of tuples and records is given away by the way you index elements in a tuple: #1, #2, ... (1, "foo", 42.0) is a derived form of (equivalent with) {1 = 1, 2 = "foo", 3 = 42.0}. This is perhaps better seen by the type that SML/NJ gives that record
- {1 = 1, 2 = "foo", 3 = 42.0};
val it = (1,"foo",42.0) : int * string * real
Note the type is not shown as a record type such as {1: int, 2: string, 3: real}. The tuple type is again a derived form of the record type.
Actually #id is not a function, and thus it can't be called with a variable as "argument". It is actually a derived form of (note the wildcard pattern row, in the record pattern match)
fn {id=var, ...} => var
So in conclusion, you won't be able to do what you wan't, since these derived forms (or syntactic sugar if you will) aren't dynamic in any ways.
One way is as Sebastian Paaske said to use lists. The drawback is that you need O(n) computations to access the nth element of a list. If you need to access an element in O(1) time, you may use arrays, which are in basic sml library.
You can find ore about arrays at:
http://sml-family.org/Basis/array.html