I was using only advance function by passing two arguments. Can somebody help me to use it with three arguments which is illustrated as:
func advance<T : ForwardIndexType>(start: T, n: T.Distance, end: T) -> T
That function increments the start index by n positions, but not
beyond the end index.
Example: You want to truncate strings to a given maximal length:
func truncate(string : String, length : Int) -> String {
let index = advance(string.startIndex, length, string.endIndex)
return string.substringToIndex(index)
}
println(truncate("fooBar", 3)) // foo
println(truncate("fo", 3)) // fo
In the first call, the start index is incremented by 3 positions,
in the second example only by two. With
let index = advance(string.startIndex, length)
the second call would crash with a runtime exception, because
a string index must not be advanced beyond the end index.
Related
If I have a sequence of values, how would I find the index of an element based on a predicate function? For example, if I had the following seq:
let values = #["pie", "cake", "ice cream"]
How would I find the index of the first element with four characters? I know of find, but it seems to only find index by equality, and does not allow passing a predicate. I could implement this myself but it feels as if it should be be in the standard library if find is.
A simple solution would be to use map from sequtils to map the predicate over the input sequence, and then to use find to get the index of the first true value in the result. This returns -1 when no element of the sequence satisfies the predicate:
import sequtils
proc isLen4(s: string): bool =
len(s) == 4
echo map(#["pie", "cake", "ice cream"], isLen4).find(true) #--> 1
This works, but is bad for large sequences since map processes the entire sequence. Thus even when the first element satisfies the predicate the entire sequence is processed. It would be better to just write a findIf procedure that returns the current index when the predicate is satisfied instead of continuing to process the rest of the input:
proc findIf[T](s: seq[T], pred: proc(x: T): bool): int =
result = -1 # return -1 if no items satisfy the predicate
for i, x in s:
if pred(x):
result = i
break
echo #["pie", "cake", "ice cream"].findIf(isLen4) #--> 1
I think I need some help with the OPL language :/
My code is the following:
using CP;
int NbMchs = ...;
range Mchs = 0..NbMchs-1;
tuple Mode {
int opId;
int mch;
int pt;
};
{Mode} Modes = ...;
// Not Working...
int test[m in Mchs] = all(md in Modes: md.mch == m) md.opId;
What I want to do is to extract m 1D arrays from the Modes structure containing just the opId field of the tuple. Each test[m] array has to contain it's corresponding elements: that is the opId field of the tuple md where md.mch =m.
The error that I get from the above code is "Cannot use type int[] for int". It seems like the right hand side of the above function is returning a single integer, but I was thinking that the all() operator is the one that I can use to do the job.
Thanks in advance
In the general case, the number of opId depends on the machine m so you cannot really have a 2-D array here. I would use an array of sets:
{int} test[m in Mchs] = { md.opId | md in Modes: md.mch == m };
Note that it assumes that you only have one mode per opId,mch.
Here is a Python-like pattern I need to re-create in Chapel.
class Gambler {
var luckyNumbers: [1..0] int;
}
var nums = [13,17,23,71];
var KennyRogers = new Gambler();
KennyRogers.luckyNumbers = for n in nums do n;
writeln(KennyRogers);
Produces the run-time error
Kenny.chpl:8: error: zippered iterations have non-equal lengths
I don't know how many lucky numbers Kenny will have in advance and I can't instantiate Kenny at that time. That is, I have to assign them later. Also, I need to know when to hold them, know when to fold them.
This is a good application of the array.push_back method. To insert lucky numbers one at a time you can do:
for n in nums do
KennyRogers.luckyNumbers.push_back(n);
You can also insert the whole array in a single push_back operation:
KennyRogers.luckyNumbers.push_back(nums);
There are also push_front and insert methods in case you need to put elements at the front or at arbitrary positions in the array.
I don't think I can help on when to hold them or when to fold them.
A way to approach this that simply makes things the right size from the start and avoids resizing/rewriting the array is to establish luckyNumbers in the initializer for Gambler. In order to do this without resizing, you'll need to declare the array's domain and set it in the initializer as well:
class Gambler {
const D: domain(1); // a 1D domain field representing the array's size
var luckyNumbers: [D] int; // declare lucky numbers in terms of that domain
proc init(nums: [?numsD] int) {
D = numsD; // make D a copy of nums's domain; allocates luckyNumbers to the appropriate size
luckyNumbers = nums; // initialize luckyNumbers with nums
super.init(); // mark the initialization of fields as being done
}
}
var nums = [13,17,23,71];
var KennyRogers = new Gambler(nums);
writeln(KennyRogers);
I need to write a method in Scala that overrides the toString method. I wrote it but I also have to check that if there is an element that is '1' I will change it to 'a', else write the list as it is with the string method. Any suggestions how this can be done?
What error are you getting? seems to work for me
val l = List(1, 2, 3)
println(this)
override def toString(): String = {
val t = l.map({
case 1 => "a"
case x => x
})
t.toString
}
getting List(a, 2, 3) printed out
I see from the comments on your question that list is a List[List[Int]].
Look at the beginning of your code:
list.map { case 1 => 'a'; case x => x}
map expects a function that takes an element of list as a parameter - a List[Int], in your case. But your code works directly on Int.
With this information, it appears that the error you get is entirely correct: you declared a method that expects an Int, but you pass a List[Int] to it, which is indeed a type mismatch.
Try this:
list.map {_.map { case 1 => 'a'; case x => x}}
This way, the function you defined to transform 1 to a and leave everything else alone is applied to list's sublists, and this type-checks: you're applying a function that expects an Int to an Int.
In the Go blog, this is how to print the map in order.
http://blog.golang.org/go-maps-in-action
import "sort"
var m map[int]string
var keys []int
for k := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
fmt.Println("Key:", k, "Value:", m[k])
}
but what if I have the string keys like var m map[string]string
I can't figure out how to print out the string in order(not sorted, in order of string creation in map container)
The example is at my playground http://play.golang.org/p/Tt_CyATTA3
as you can see, it keeps printing the jumbled strings, so I tried map integer values to map[string]string but I still could not figure out how to map each elements of map[string]string.
http://play.golang.org/p/WsluZ3o4qd
Well, the blog mentions that iteration order is randomized:
"...When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next"
The solution is kind of trivial, you have a separate slice with the keys ordered as you need:
"...If you require a stable iteration order you must maintain a separate data structure that specifies that order."
So, to work as you expect, create an extra slice with the correct order and the iterate the result and print in that order.
order := []string{"i", "we", "he", ....}
func String(result map[string]string) string {
for _, v := range order {
if present in result print it,
}
... print all the Non-Defined at the end
return stringValue
}
See it running here: http://play.golang.org/p/GsDLXjJ0-E