[Solved]How to get subset of list data use "::" cons in Sophia?


#1

contract Stack =

type state = { stack : list(string),
size : int }

function init(ss) = { stack = ss, size = length(ss) }

private function length(xs) =
switch(xs)
[] => 0
_ :: xs => length(xs) + 1

stateful function pop() : string =
switch(state.stack)
s :: ss =>
put(state{ stack = ss, size = state.size - 1 })
s

stateful function push(s) =
put(state{ stack = s :: state.stack, size = state.size + 1 })
state.size

function all() = state.stack

function size() = state.size

Q:
The pop function only get one element data of stack list, and how to get 3 element or more element one time ? Thank you.


#2

It’s a little complicated. :neutral_face:


#3
function pop_n(n : int) = pop_n(n, [])
private function pop_n(n, xs) =
  switch(n)
    0 => xs
    _ => pop_n(n - 1, pop() :: xs)

#4

@hanssv
Thank you for your code, the pop_n function just remove the “n” top data of the list, how can i just return some of the data on the top of list , It is also change the contract status, It’s there a better way for get the subset of list data without change the contract status, just use the static call.
Ex:
let a = ( (1, 1, 1), (2, 2, 2,), (3, 3, 3), (4, 4, 4,) … (n, n, n, ) )

How to return (1, 1, 1), (2, 2, 2,), (3, 3, 3) or more, without change the contract status. Thank you.


#5
function peek_n(n : int) = get_n(n, state.stack) 
private function get_n(n, s) = 
  switch(n) 
    0 => [] 
    _ => 
       switch(s)
         [] => []
         x :: s' => x :: get_n(n - 1,  s')

Where you can use get_n to get n elements out of any list…


#6

Thank you very much ! Fantastic code.