I have started learning scala and I wonder is there a way I could get elements in the List from the right side
For example
val myList = List(1, 2, 3, 4, 5)
if I writemyList(-1) I would get 5.
Is there any simple way to get it done or I'll have to write my own function?
myList.last
? Remember that this operation has O(n) complexity for List. Also you can simply reverse the list and use normal indices:
myList.reverse(0)
Scala's List is a singly linked list, and therefore indexed lookup on it would be a linear time operation. Since you are interested in backward indices, you'll also have to call .length method, which is a linear time operation as well.
If you need to perform indexed access, List is probably not the right data structure to use. You should instead use Vector which is a sequence type with efficient indexed access (takes constant time effectively).
Refer this link for an overview of performance characteristics of various Scala collections.
scala> val v = Vector(3, 4, 5, 2)
v: scala.collection.immutable.Vector[Int] = Vector(3, 4, 5, 2)
scala> v(v.length - 1)
res21: Int = 2
myList(myList.length-1-index)
Note then myList.length has O(n) complexity, and querying for specific index has O(index).
To do something like:
myList(-n)
You can define an implicit conversion that lets you do:
myList.getFromRight(n)
Here is the code for the implicit conversion. It will create a new getFromRight method on all Seqs, so it will work on Lists, Vectors, etc.
implicit def getFromRightImpl[A](s: Seq[A]) = new {
def getFromRight(n: Int) = s(s.length - n)
}
And here are some examples:
scala> val v = Vector(1, 2, 3, 4)
v: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4)
scala> val l = List(1, 2, 3, 4)
l: List[Int] = List(1, 2, 3, 4)
scala> v.getFromRight(1)
res4: Int = 4
scala> l.getFromRight(3)
res5: Int = 2
Implicit conversions are a rather advanced Scala feature, but this is one of the perfect use cases for them: when an object is lacking methods you think it should have, but modifying it with inheritance is not an option, you can define an implicit conversion to another object with the methods you want.
Related
I am attempting to learn C++ from scratch and possess a medium amount of python knowledge.
Here is some of my python code which takes a number, turns it into a list and checks if it contains all digits 0-9. If so it returns True, if not it returns False.
def val_checker(n):
values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lst = []
for i in range(len(str(n))):
lst.append((n // 10 ** i) % 10)
lst = lst[::-1]
return all(i in lst for i in values)
How would I achieve a similar thing in C++?
You would use the standard library container std::set or better yet std::unordered_set
This container will hold at most one of each distinct element, duplicates insertions are ignored.
So you can run through your original number in a loop, adding each digit into the set, and consider success if s.size() == 10 if your set is called s
I'm wondering if there is a functional way to apply an action to every element of list, in Maxima, without necessarily looping over the list?
e.g. if I would like to remove every element of the list a:[1,2,3] from the list b:[5,4,3,2,1]. Obviously, something like:
f(a,b):=
block(
[aList:a, newList:b],
for k thru length(aList)
do newList: delete(aList[k],newList)
);
I just wondered if there was a more direct way? I thought apply might work, but couldn't figure it out, as it seems to take the whole list as the argument (vs. list elements).
There are a few different ways to accomplish that. One way is to treat the arguments as sets and apply setdifference.
(%i2) a: [1, 2, 3] $
(%i3) b: [5, 4, 3, 2, 1] $
(%i4) setify(a);
(%o4) {1, 2, 3}
(%i5) setify(b);
(%o5) {1, 2, 3, 4, 5}
(%i6) setdifference (setify(b), setify(a));
(%o6) {4, 5}
(%i7) listify(%);
(%o7) [4, 5]
That works if a and b are really sets, i.e. order doesn't matter, and elements are unique.
Another way:
(%i8) sublist (b, lambda ([x], not member(x, a)));
(%o8) [5, 4]
I guess the sublist approach makes fewer assumptions, so it is more generally applicable.
I have a list in dart I want to initialize the list with n number of the same element.
example:- initialize the integer list with element 5 4 times.
List<int> temp = [5,5,5,5];
what are different ways to initialize the list in dart flutter?
The easiest way I can think of is List.filled:
List.filled(int length, E fill, { bool growable: false }).
The params would be:
length - the number of elements in the list
E fill - what element should be contained in the list
growable - if you want to have a dynamic length;
So you could have:
List<int> zeros = List.filled(10, 0)
This would create a list with ten zeros in it.
One think you need to pay attention is if you're using objects to initialise the list for example:
SomeObject a = SomeObject();
List<SomeObject> objects = List.filled(10, a);
The list created above will have the same instance of object a on all positions.
If you want to have new objects on each position you could use List.generate:
List.generate(int length, E generator(int index), {bool growable:true})
Something like:
List<SomeObject> objects = List<SomeObject>.generate(10, (index) => SomeObject(index);
OR:
List<SomeObject> objects = List<SomeObject>.generate(10, (index) {
SomeOjbect obj = SomeObject(index)
obj.id= index;
return obj;
});
This will create a new instance for each position in list. The way you initialise the object is up to you.
You can try like this
List<int>.generate(4, (int index) => 5);
For more, read this
Here is a simplified version of the accepted answer. You can use a list literal, a filled list, or a generated list:
final literal = [5, 5, 5, 5];
final filled = List.filled(4, 5);
final generated = List.generate(4, (index) => 5);
print(literal); // [5, 5, 5, 5]
print(filled); // [5, 5, 5, 5]
print(generated); // [5, 5, 5, 5]
When you just want to fill the list with the same values, List.filled is good. Unless you literally want [5, 5, 5, 5]. In that case, just use the list literal. It's easy to read and understand.
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
How to transform a list (row) into the subsequent one without loop - just using list.reduce(...) in Js, Kotlin, Scala, Swift or Java 8 Streams or whatever?
To me this looks a lot like a discussion based on definitions. In many languages reduce only means function of following signature (some types imaginary syntax)
(coll: Collection[T], operation: (value:T, accumulator:T) => T) => T
In other words reduce only reduces elements of the collection into result of the same type. Under such definition you obviously can't get a new array from an array of integers. However in both JavaScript and Java 8 Streams there is actually a reduce version which is closer to what other people might call fold (which is what it is called for example in Kotlin) with a more advanced signature such as
(coll: Collection[T], initialValue : U, operation: (value:T, accumulator:U) => U) => U
Using such reduce you can build the next row in the Pascal's triangle. For example using JavaScript:
const buildNext = arr => arr.reduce((acc,val) => {
acc[acc.length - 1] += val;
acc.push(val);
return acc;
},
[0]); // initial accumulator
console.log(buildNext[1,3,3,1]);
Note that in Java 8 Streams version the code will be more complicated because Streams were designed with parallel computation in mind so you have to provide one more function to join 2 accumulators of different segments.
This is Sergr's solution rewritten to kotlin with immutable lists:
fun nthRowOfPascalTriangleRecursively(n: Long): List<Long> = when (n) {
0L -> listOf(1)
else -> nthRowOfPascalTriangleRecursively(n - 1)
.fold(listOf(0L)) { acc, it -> acc.dropLast(1) + (acc.last() + it) + listOf(it) }
}
Let say I have some values in a List. I would like to return another list with a new element
fun newList():List<Int>{
val values =listOf<Int>(1,2,3,4,5,6);
return 7::values; // something like that
}
The Kotlin lists have the plus operator overloaded in kotlin-stdlib, so you can add an item to a list:
val values = listOf(1, 2, 3, 4, 5, 6)
return values + 7
There's also an overload that adds another list:
val values = listOf(1, 2, 3, 4, 5, 6)
return listOf(-1, 0) + values + listOf(7, 8)
Note that in both cases a new list is created, and the elements are copied into it.
For MutableList<T> (which has mutating functions, in contrast with List<T>), there is a plusAssign operator implementation, that can be used as follows:
fun newList(): List<Int> {
val values = mutableListOf(1, 2, 3, 4, 5, 6)
values += 7
values += listOf(8, 9)
return values
}
A different approach by using spread operator. Maybe in some case would be simpler than using + sign or mutableListOf
fun newList(): List<Int>{
val values = listOf(1,2,3,4,5,6)
return listOf(7, *values.toTypedArray(), 8, 9)
}
You can do it like this
fun newList():List<Int>{
val values =listOf(1,2,3,4,5,6) //Type can be inferred
return values.plus(7)
}
I wanted a Scala-like with for and yield. It's pretty good in - currently experimental - coroutines :
fun testYield(max:Int): List<Int> {
val values = buildSequence{
for (i in 1..max){
yield(i)
}
}
return values.toList();
}
Or in shorter way:
fun testYieldFast(max: Int) = buildSequence {
for (i in 1..max)
yield(i)
}.toList();
It allows fast immutable lazy construction, where frequent concatenation are usually slow with immutable lists.