List<int> myList = [1,2,3];
int i = 2;
myList[i] = 4; // myList = [1,2,4]
but what if i don't know whether myList contains data at specific index? Then it gives me range error.
i = 4;
myList[i] = 4 // range error
if(myList[i] != null) myList[i] = 4 //range error
myList.insert(i, 4) // i want to replace, not shift values.
Is the only way to replace the list value at specific index is by checking the whole list length first?
Here is the example that you can check the index before and If that condition is true then only it will update the value.
void main() {
List<int> myList1 = [1,2,3];
int i = 2;
if(myList1.length> i) myList1[i] = 4; // myList = [1,2,4]
myList1.forEach(print);
int j = 5;
if(myList1.length> j) myList1[j] = 4; // myList = [1,2,4]
myList1.forEach(print); // It will print as it is last one.
}
Thank you.
From what I understood, you want to know if there is any other way to check whether or not the index exists for your list.
If So then:
List<int> myList = [1,2,3];
int i = 2;
if(myList.asMap().containsKey(i)) myList[i] = 4
Let me know if I understood your question correctly.
try like this:
if(i<=myList.length){
myList[i]=4;
}
Related
I am creating an app right now and I want to get the difference between two lists such:
List x = ['one' , 'two' , 'three' , 'four'];
List y = ['one' , 'two',];
------
Output: ['three' , 'four']
This might be easier if you can use Set.difference instead.
If you're stuck with using lists this is a slightly shorter solution.
var l = [1, 2, 3, 4];
var r = [3, 4];
l.removeWhere((e) => r.contains(e));
print(l);
You can loop through one of the loop and then check if the item is present in the other list or not.
void main() {
List x = ['one' , 'two' , 'three' , 'four'];
List y = ['one' , 'two',];
List output = [];
for(final e in x){
bool found = false;
for(final f in y) {
if(e == f) {
found = true;
break;
}
}
if(!found){
output.add(e);
}
}
print(output);
}
we had to implement the insert function that can insert a cell into a sorted linked list. My implementation idea was to have two rlists, called previous and current, that will be used to iterate through the list. At the beginning of the function call, the previous rlist will contain a random integer, and its next field is pointing to the current cell which is the head of the linked_list. I think this is problematic. I finished implementing my idea. I think the method will add the correct integer at the right place in the linked list. However, if the inserted element is at the beginning of the list, then the list is still the old list when using displaying on to the screen, but the old list does indeed have a cell pointing to it, and that cell has the inserted integer. So I'm not sure how to deal with that.
I tested my method, and it doesn't work as I described.
Here is what I did: I inserted -9 to the end of c3. c3 does indeed get -9 at the end of the list. And then I added 4 inside c5. But then c5 now becomes [5;4;-9]. So it is wrong, it should have [5;4;3;2;1;-9] instead. So I don't know what is wrong.
I looked up online on how to implement the method so that they can give me some inspirations or hint, but the solutions they provided are usually in Java or other programming languages.
type cell = { data : int; next : rlist}
and rlist = cell option ref
let c1 = {data = 1; next = ref None}
let c2 = {data = 2; next = ref (Some c1)}
let c3 = {data = 3; next = ref (Some c2)}
let c5 = {data = 5; next = ref (Some c3)}
let rec displayList (c : rlist) =
match !c with
| None -> []
| Some { data = d; next = l } -> d :: (displayList l)
let cell2rlist (c : cell) :rlist = ref (Some c)
let bigger((x:int), (y:int)) = (x > y)
let insert (comp : (int * int) -> bool) (item : int) (listt :rlist)=
let itemm = {data=item ; next = ref None} in
let rec helper (prev : rlist) (item : cell) (current: rlist) funcc =
match !current with
|None -> (match !prev with
|Some w -> w.next := (Some itemm))
|Some q -> if comp (item.data, q.data) then (itemm.next := (Some q) ; match !prev with
|Some w -> w.next := (Some itemm))
else prev := !current; current:= !(q.next); (helper prev item current funcc)
in let previous = ref (Some {data=0; next = listt}) in
helper previous itemm listt comp
Here are examples of the right return values for the code in action:
let l5 = cell2rlist c5;;
val l5 : rlist = ....
(* Messy display deleted. *)
displayList l5;;
- : int list = [5; 3; 2; 1]
displayList l5;;
- : int list = [5; 3; 2; 1]
insert bigger 4 l5;;
- : unit = ()
displayList l5;;
- : int list = [5; 4; 3; 2; 1]
insert bigger 9 l5;;
- : unit = ()
displayList l5;;
- : int list = [9; 5; 4; 3; 2; 1]
insert bigger 0 l5;;
- : unit = ()
displayList l5;;
- : int list = [9; 5; 4; 3; 2; 1; 0]
But when I ran my codes, here is what I get:
insert bigger 10 (ref(Some c5)) ;;
- : unit = ()
c5 ;;
- : cell =
{data = 5;
next =
{contents =
Some
{data = 3;
next =
{contents =
Some
{data = 2;
next = {contents = Some {data = 1; next = {contents = None}}}}}}}}
As you can see, if I insert a number that is supposed to be inserted at the beginning of the list, I can't see it.
Here is another example,
insert bigger 4 (ref(Some c5)) ;;
- : unit = ()
c5 ;;
- : cell =
{data = 5;
next =
{contents =
Some
{data = 4;
next = {contents = Some {data = 1; next = {contents = None}}}}}}
So as you see the code doesn't work at all as the updated list should have values [5;4;3;2;1] but it has [5;4;1] instead.
Here is another example:
insert bigger (-9) (ref(Some c3)) ;;
- : unit = ()
c3 ;;
- : cell =
{data = 3;
next =
{contents =
Some
{data = 2;
next =
{contents =
Some
{data = 1;
next = {contents = Some {data = -9; next = {contents = None}}}}}}}}
So it seems that the method does insert the element correctly into the list, but the lists that the inserted cell suppose to point to seem to be wrong.
For reference, here is a session showing a failure of your code:
# let (l: rlist) = ref None;;
val l : rlist = {contents = None}
# insert bigger 1 l;;
- : unit = ()
# l;;
- : rlist = {contents = Some {data = 1; next = {contents = None}}}
# insert bigger 0 l;;
- : unit = ()
# l;;
- : rlist = {contents = None}
For what it's worth, it would also be good if your code was indented properly.
At any rate, what I see when I look at your code for a short time is this fragment:
current:= !(q.next);
helper prev item current funcc
It looks to me like you're imagining that the first line here will advance some local variable to point to the next element of the list. But what it actually is doing is modifying the list.
You might want something more like this:
helper prev item q.next funcc
There are other problems in your code as well. It seems odd, for example, that the then part is parenthesized but the else part isn't parenthesized.
I'm working on an assignment and was given the following function:
fun label (lb,ub) =
let val s = callcc (fn k =>let fun branch c = if (c < ub)
then (pushCP (k,branch,c+1);c)
else ub
in (pushCP(k,branch,lb+1);lb)
end)
in {value=s,dom=(lb,ub)}
end;
If you put a lower and upper bound of let's say 1 and 3into this function it would print
val it = {dom=(1,3), value=1}
What I am trying to figure out is if it is at all possible to get the value. In my notes it says two possible ways of doing this would be through #value(x) or by doing val {value=a,...} = x, but I get errors both ways with this.
Any clue what I am doing wrong?
It isn't clear what you are doing wrong since you haven't reproduced what you actually tried, but your notes are correct:
- val x = {dom=(1,3), value=1};
val x = {dom=(1,3),value=1} : {dom:int * int, value:int}
The first method is to use #value to extract the value field and #dom to extract the dom field:
- #value x;
val it = 1 : int
- #dom x;
val it = (1,3) : int * int
The second method is to use pattern matching. You can extract individual fields:
- val {value = a,...} = x;
val a = 1 : int
Or you can extract both fields at once:
- val {dom = a, value = b} = x;
val a = (1,3) : int * int
val b = 1 : int
In order for the above to work, x needs to be bound to the value. Perhaps you are trying to use this with an x which hasn't been given a val binding. You would need to have something like this:
val x = label(1,3)
I don't have all the relevant code so I can't test. If the above isn't enough to answer your question, you need to provide more details.
Supposing I have a type defined as follows:
type State = { intList : int list }
and a value as follows:
let a = { intList = [1; 2; 3; 4] }
Now supposing I want a new value b with a's values with 5 added to the end. I can't figure out how to do it using the with syntax. Also I can't figure out how to get a new state having one fewer element, for example.
The with syntax (copy-and-update expression) doesn't allow for creating a record based on a modified property of another record, only copying some properties (intact) and replacing others. You can use normal record constructors:
let a = { intList = [1; 2; 3; 4] }
let b = { intList = a.intList # [1; 2; 3; 4; 5] }
let c = { intList = List.tail a.intList }
As Daniel said, there is no specific syntax to read a property from the record you are copy-and-updating. But you still can access it using normal dot notation:
let a = { intList = [1; 2; 3; 4] }
let b = { a with intList = a.intList # [5] }
Of course, in this case the with is pretty useless since you're updating all the fields, so you might as well just use the new record syntax (as shown by Daniel). But if the record also has fields that you want to preserve from a to b, this is how I would do it.
Newbie to scala.
I am trying to make this code to work for a few hours now . It is intended to update the List[Int](list of integers) with absolute values of the integers.
Took a long time to figure out that List is immutable, so found that ListBuffer can be the saviour, but eventually in returning it back into the List form is seeing some issue i guess.
def f (arr:List[Int]) : List[Int] =
{
val list = new scala.collection.mutable.ListBuffer[Int]();
val len = arr.length;
for ( i <- 0 to len)
{
if(arr(i) < 0)
{
list.append((-1)*arr(i)) ;
}
else
{
list.append(arr(i));
}
}
return list.toList;
}
which is giving this error:
java.lang.IndexOutOfBoundsException: 12
at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:52)
at scala.collection.immutable.List.apply(List.scala:84)
at Solution$.f(Solution.scala:7)
at Solution$delayedInit$body.apply(Solution.scala:23)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:71)
at scala.App$$anonfun$main$1.apply(App.scala:7...
Not getting what's wrong here.
The best way is to use Scala functions like #senia suggested in comments. For example:
val res = list map math.abs
But if you want to fix your code just replace to with until. You are getting off by one error:
def f (arr:List[Int]) : List[Int] =
{
val list = new scala.collection.mutable.ListBuffer[Int]();
val len = arr.length;
for ( i <- 0 until len)
{
if(arr(i) < 0)
{
list.append((-1)*arr(i)) ;
}
else
{
list.append(arr(i));
}
}
return list.toList;
}
Here is the difference between until and to:
1 to 3
// Range(1, 2, 3)
1 until 3
// Range(1, 2)
You can also remove return, ; and even braces { used with if/else.
Yet another version using a for comprehension that avoids indexing,
def f (arr:List[Int]) : List[Int] =
{
val list = new scala.collection.mutable.ListBuffer[Int]();
for {
a <- arr
sign = if (a < 0) -1 else 1
} list.append(sign * a)
return list.toList;
}
As mentioned above, the return may be omitted.
You can try using case statements for more neat syntax :
def f(arr:List[Int]):List[Int] = {
val list = scala.collection.mutable.ListBuffer[Int]()
arr.foreach{
x =>
x match {
case _ if (x <0) => list+= (x*(-1))
case _ => list +=x
}
}
list.toList
}
Looks like you were trying to solve the challenge from here. Probably you may want to use more functional approach with recursion and immutable List.
def f(arr: List[Int]): List[Int] = arr match {
case Nil => Nil
case x :: rest => java.lang.Math.abs(x) :: f(rest)
}
Beginner friendly: this is how I wrote it
def f(arr: List[Int]) : List[Int] = {
var list = new scala.collection.mutable.ArrayBuffer[Int]();
// var len = arr.length;
for(i <-0 until arr.length) {
list.append( math.abs(arr(i)));
}
return list.toList; }
I haven't done any time complexity analysis but it's the most straightforward for beginners to understand. Also, it passes all the tests on hackerrank
def f (arr: List[Int]) : List[Int] = {
arr.map {
case i if 0 > i => i * -1
case i => i
}
}