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

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.

It’s a little complicated.

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

@hanssv.chain
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.

``````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…

Thank you very much ! Fantastic code.

1 Like