I have a list of A class objects
data class A{
val abc: Abc
val values: Int?
}
val list = List<A>
If I want to count how many objects I have in list I use:
val count= a.count()
or val count= a.count(it -> {})
How to append all values in the list of objects A avoiding for loop? Generaly Im looking for proper kotlin syntax with avoiding code below
if (a!= null) {
for (i in list) {
counter += i.values!!
}
}
Either use sumBy or sum in case you have a list of non-nullable numbers already available, i.e.:
val counter = list.sumBy { it.values ?: 0 }
// or
val counter = extractedNonNullValues.sum()
The latter only makes sense if you already mapped your A.values before to a list of non-nullable values, e.g. something like:
val extractedNonNullValues= list.mapNotNull { it.values } // set somewhere else before because you needed it...
If you do not need such an intermediate extractedNonNullValues-list then just go for the sumBy-variant.
I don't see you doing any appending to a list in the question. Based on your for loop I believe what you meant was "How do I sum properties of objects in my list". If that's the case you can use sumBy, the extension function on list that takes a labmda: ((T) -> Int) and returns an Int like so:
val sum = list.sumBy { a -> a.values ?: 0 }
Also, calling an Int property values is pretty confusing, I think it should be called value. The plural indicates a list...
On another note, there is a possible NPE in your original for loop. Avoid using !! on nullable values as, if the value is null, you will get an NPE. Instead, use null coalescing (aka elvis) operator to fall back to a default value ?: - this is perfectly acceptable in a sum function. If the iteration is not to do with summing, you may need to handle the null case differently.
Related
So I got a question that was delivered as a 2D List
val SPE = listOf(
listOf('w', 'x'),
listOf('x', 'y'),
listOf('z', 'y'),
listOf('z', 'v'),
listOf('w', 'v')
)
It asks to find the shortest path between w and z. So obviously, BFS would be the best course of action here to find that path the fastest. Here's my code for it
fun shortestPath(edges: List<List<Char>>, root: Char, destination: Char): Int {
val graph = buildGraph3(edges)
val visited = hashSetOf(root)
val queue = mutableListOf(mutableListOf(root, 0))
while (queue.size > 0){
val node = queue[0].removeFirst()
val distance = queue[0].removeAt(1)
if (node == destination) return distance as Int
graph[node]!!.forEach{
if (!visited.contains(it)){
visited.add(it)
queue.add(mutableListOf(it, distance + 1))
}
}
}
queue.sortedByDescending { it.size }
return queue[0][1]
}
fun buildGraph3(edges: List<List<Char>>): HashMap<Char, MutableList<Char>> {
val graph = HashMap<Char, MutableList<Char>>()
for (i in edges.indices){
for (n in 0 until edges[i].size){
var a = edges[i][0]
var b = edges[i][1]
if (!graph.containsKey(a)) { graph[a] = mutableListOf() }
if (!graph.containsKey(b)) { graph[b] = mutableListOf() }
graph[a]?.add(b)
graph[b]?.add(b)
}
}
return graph
}
I am stuck on the return part. I wanted to use a list to keep track of the incrementation of the char, but it wont let me return the number. I could have done this wrong, so any help is appreciated. Thanks.
If I paste your code into an editor I get this warning on your return queue[0][1] statement:
Type mismatch: inferred type is {Comparable<*> & java.io.Serializable} but Int was expected
The problem here is queue contains lists that hold Chars and Int distances, mixed together. You haven't specified the type that list holds, so Kotlin has to infer it from the types of the things you've put in the list. The most general type that covers both is Any?, but the compiler tries to be as specific as it can, inferring the most specific type that covers both Char and Int.
In this case, that's Comparable<*> & java.io.Serializable. So when you pull an item out with queue[0][1], the value you get is a Comparable<*> & java.io.Serializable, not an Int, which is what your function is supposed to be returning.
You can "fix" this by casting - since you know how your list is meant to be organised, two elements with a Char then an Int, you can provide that information to the compiler, since it has no idea what you're doing beyond what it can infer:
val node = queue[0].removeFirst() as Char
val distance = queue[0].removeAt(1) as Int
...
return queue[0][1] as Int
But ideally you'd be using the type system to create some structure around your data, so the compiler knows exactly what everything is. The most simple, generic one of these is a Pair (or a Triple if you need 3 elements):
val queue = mutableListOf(Pair<Char, Int>(root, 0))
// or if you don't want to explicitly specify the type
val queue = mutableListOf(root to 0)
Now the type system knows that the items in your queue are Pairs where the first element is a Char, and the second is an Int. No need to cast anything, and it will be able to help you as you try to work with that data, and tell you if you're doing the wrong thing.
It might be better to make actual classes that reflect your data, e.g.
data class Step(node: Char, distance: Int)
because a Pair is pretty general, but it's up to you. You can pull the data out of it like this:
val node = queue[0].first
val distance = queue[0].second
// or use destructuring to assign the components to multiple variables at once
val (node, distance) = queue[0]
If you make those changes, you'll have to rework some of your algorithm - but you'll have to do that anyway, it's broken in a few ways. I'll just give you some pointers:
your return queue[0][1] line can only be reached when queue is empty
queue[0].removeAt(1) is happening on a list that now has 1 element (i.e. at index 0)
don't you need to remove items from your queue instead?
when building your graph, you call add(b) twice
try printing your graph, the queue at each stage in the loop etc to see what's happening! Make sure it's doing what you expect. Comment out any code that doesn't work so you can make sure the stuff that runs before that is working.
Good luck with it! Hopefully once you get your types sorted out things will start to fall into place more easily
I stumbled upon this challenge on stackoverflow while learning about property based testing in scala using ScalaCheck.
Find the smallest positive integer that does not occur in a given sequence
I thought of trying to write a generator driven property based test for this problem to check the validity of my program but can't seem to be able to think of a how to write a relevant test case. I understand that I could write a table driven property based testing for this use case but that limit the number of properties I could test this algo with.
import scala.annotation.tailrec
object Solution extends App {
def solution(a: Array[Int]): Int = {
val posNums = a.toSet.filter(_ > 0)
#tailrec
def checkForSmallestNum(ls: Set[Int], nextMin: Int): Int = {
if (ls.contains(nextMin)) checkForSmallestNum(ls, nextMin + 1)
else nextMin
}
checkForSmallestNum(posNums, 1)
}
}
Using Scalatest's (since you did tag scalatest) Scalacheck integration and Scalatest matchers, something like
forAll(Gen.listOf(Gen.posNum[Int]) -> "ints") { ints =>
val asSet = ints.toSet
val smallestNI = Solution.solution(ints.toArray)
asSet shouldNot contain(smallestNI)
// verify that adding non-positive ints doesn't change the result
forAll(
Gen.frequency(
1 -> Gen.const(0),
10 -> Gen.negNum[Int]
) -> "nonPos"
) { nonPos =>
// Adding a non-positive integer to the input shouldn't affect the result
Solution.solution((nonPos :: ints).toArray) shouldBe smallestNI
}
// More of a property-based approach
if (smallestNI > 1) {
forAll(Gen.oneOf(1 until smallestNI) -> "x") { x =>
asSet should contain(x)
}
} else succeed // vacuous
// Alternatively, but perhaps in a less property-based way
(1 until smallestNI).foreach { x =>
asSet should contain(x)
}
}
Note that if scalatest is set to try forAlls 100 times, the nested property check will check values 10k times. Since smallestNI will nearly always be less than the number of trials (as listOf rarely generates long lists), the exhaustive check will in practice be faster than the nested property check.
The overall trick, is that if something is the least positive integer for which some predicate applies, that's the same as saying that for all positive integers less than that something the predicate does not apply.
I have a map that has a few key value pairs, and I would like a way to go through those pairs and attempt to match the keys with the value of another map. If there's a match the values are substituted for each other. In other words, if there's a match value of the second map is substituted for the value of the first map. If there is no match, it is not included in the result.
I've tried figuring out the logic use the scala .map function but I'm new to scala and can't quite figure it out.
For example, I have the following two scala Map[String, String]:
val lookupMap = Map("aaa" -> "apple", "bbb" -> "orange", "ccc" -> "banana")
val entriesMap = Map("foo" -> "ccc", "bar"-> "aaa", "baz" -> "zzz")
I would like some way to get the following result:
val result = Map("foo" -> "banana", "bar" -> "apple")
Note: "baz" was not included because it did not match to anything in the lookup Map.
A for comprehension can clean that up.
val result = for {
(k,ev) <- entriesMap
lv <- lookupMap.get(ev)
} yield (k,lv)
//result: Map[String,String] = Map(foo -> banana, bar -> apple)
Lets break down your problem in simpler steps.
Filter out all pairs on the entriesMap whose value does not exists as a key in the lookupMap.
Map the remaining pairs to change the value for the value on the lookupMap associated with the original value.
Thus, you can write the following:
val result =
entriesMap
.filter { case (_, value) => lookupMap.contains(key = value) }
.map { case (key, value) => key -> lookupMap(value) }
However, every time that you want to filter and then map, you can always use collect (which will do the same job, but in just one iteration).
Thus, you can write this:
val result = entriesMap.collect {
case (key, value) if lookupMap.contains(key = value) => key -> lookupMap(value)
}
Now, one "problem" with the above code is that it uses the unsafe apply over a Map, which will throw an exception if they key does not exists.
Usually, one should use the get method, which would return the value wrapped on an Option, which will be a None if the key did not existed.
In this case, the access is not unsafe, because we are checking if the key exists before.
Anyways, one could rethink the program as:
Map the values of the entriesMap by attempting to get their associated value on the lookupMap.
Filter out the pairs where its values is now a None and unwrapping the Somes.
The code will be as follows:
val result =
entriesMap
.view // Only if you are in 2.13
.mapValues(value => lookupMap.get(key = value))
.collect { case (key, Some(value)) => key -> value }
.toMap // This is necessary because mapValues returns a view, which is a lazy collection.
// Other option would have been to use just map instead of mapValues.
Finally, instead of using higher order functions directly, one could use for comprehension.
Thus, this code (almost the same as the one from jwvh's answer):
val result =
for {
(key, value) <- entriesMap // For each key-value pair in entriesMap...
newValue <- lookupMap.get(key = value) // And for each newValue associated with each original value...
} yield key -> newValue // Yield the key-newValue pair.
I wonder what is the real use of passing a closure object to a method.
Lets say I have a closure :
def a = {
println it
}
(Consider it is doing some sort of operation rather than just printing)
Now I'm just passing this closure a to a method :
def testMethod(def input,Closure a){
a(input)
}
testMethod "MethodPointer", a //passing closure.
Now the question is why this level of indirection? Why can't testMethod directly process its input? Yes, here I'm making input to be processed in closure a, but why one should do so?. What is the real use of passing closure around?
Thanks in advance.
How would you write the collect method without Closures for parameters? It would be a lot more complex than it is currently. The same goes for Builders, inject, each, with and many more...
It allows you to define something generic, and then make it more specific at a later date. For example, the collect method could be described as "takes a collection or iterable, and for each element DO SOMETHING and add it to a newly created collection". Without Closures to specify this DO SOMETHING at a later date, the value of collect would be minimal.
Slowly, you come to a more functional way of thinking. Rather than writing a specific function to perform a specific task, could I write a function which takes more of a generalist approach applicable to multiple problems, and put the specifics for each individual case in a Closure?
Edit
As an example, consider this procedural method which returns a List of the numbers between min and max which are multiples of mult:
List<Integer> filter( int min, int max, int mult ) {
List<Integer> multiples = new ArrayList<Integer>() ;
for( int i = min ; i < max ; i++ ) {
if( i % mult == 0 ) {
multiples.add( i ) ;
}
}
multiples
}
println filter( 1, 200, 15 )
If we write this in Groovy using Closures (for the filtering), we get:
List<Integer> filter( int min, int max, int mult ) {
(min..max).findAll { it % mult == 0 }
}
println filter( 1, 200, 15 )
(I accept that this example is basically mirroring the functionality of findAll, so probably isn't a great example -- and is also somewhat contrived)
Now consider that we want to filter based on some other criteria (that the integer exists in a database or something)... We could first rewrite our filter method to:
List<Integer> filter( int min, int max, Closure<Boolean> filter ) {
(min..max).findAll filter
}
println filter( 1, 200 ) { it % 15 == 0 }
Then, as you can see, we can pass any closure to this method that returns true if we want to keep the element, or false if we want to drop it.
To do this in an imperative style, you're going to (probably) end up with multiple methods all doing very similar tasks...
The idea is to write modular and structured clear code.
I wrote a blog post about Closure Design Patterns. You can find some examples of patterns using closures.
I have this LINQ Query:
TempRecordList = new ArrayList(TempRecordList.Cast<string>().OrderBy(s => s.Substring(9, 30)).ToArray());
It works great and performs sorting in a way that's accurate but a little different from what I want. Among the the result of the query I see something like this:
Palm-Bouter, Peter
Palmer-Johnson, Sean
Whereas what I really need is to have names sorted like this:
Palmer-Johnson, Sean
Palm-Bouter, Peter
Basically I want the '-' character to be treated as being lower than the character so that names that contain it show up later in an ascending search.
Here is another example. I get:
Dias, Reginald
DiBlackley, Anton
Instead of:
DiBlackley, Anton
Dias, Reginald
As you can see, again, the order is switched due to how the uppercase letter 'B' is treated.
So my question is, what do I need to change in my LINQ query to make it return results in the order I specified. Any feedback would be greatly appreaciated.
By the way, I tried using s.Substring(9, 30).ToLower() but that didn't help.
Thank you!
To customize the sorting order you will need to create a comparer class that implements IComparer<string> interface. The OrderBy() method takes comparer as second parameter.
internal sealed class NameComparer : IComparer<string> {
private static readonly NameComparer DefaultInstance = new NameComparer();
static NameComparer() { }
private NameComparer() { }
public static NameComparer Default {
get { return DefaultInstance; }
}
public int Compare(string x, string y) {
int length = Math.Min(x.Length, y.Length);
for (int i = 0; i < length; ++i) {
if (x[i] == y[i]) continue;
if (x[i] == '-') return 1;
if (y[i] == '-') return -1;
return x[i].CompareTo(y[i]);
}
return x.Length - y.Length;
}
}
This works at least with the following test cases:
var names = new[] {
"Palmer-Johnson, Sean",
"Palm-Bouter, Peter",
"Dias, Reginald",
"DiBlackley, Anton",
};
var sorted = names.OrderBy(name => name, NameComparer.Default).ToList();
// sorted:
// [0]: "DiBlackley, Anton"
// [1]: "Dias, Reginald"
// [2]: "Palmer-Johnson, Sean"
// [3]: "Palm-Bouter, Peter"
As already mentioned, the OrderBy() method takes a comparer as a second parameter.
For strings, you don't necessarily have to implement an IComparer<string>. You might be fine with System.StringComparer.CurrentCulture (or one of the others in System.StringComparer).
In your exact case, however, there is no built-in comparer which will handle also the - after letter sort order.
OrderBy() returns results in ascending order.
e comes before h, thus the first result (remember you're comparing on a substring that starts with the character in the 9th position...not the beginning of the string) and i comes before y, thus the second. Case sensitivity has nothing to do with it.
If you want results in descending order, you should use OrderByDescending():
TempRecordList.Cast<string>
.OrderByDescending(s => s.Substring(9, 30)).ToArray());
You might want to just implement a custom IComparer object that will give a custom priority to special, upper-case and lower-case characters.
http://msdn.microsoft.com/en-us/library/system.collections.icomparer.aspx