List in Scol » History » Version 1
iri, 09/24/2012 10:17 PM
| 1 | 1 | iri | h1. List in Scol |
|---|---|---|---|
| 2 | |||
| 3 | Lists are very common in Scol. |
||
| 4 | A list can be extended dynamically. Its use memory can increase and, in a long list, the accessing an element can take a "long" time. |
||
| 5 | |||
| 6 | A list is always a tuple with two element : the first element and the next of the list. This next is itself composed of the first element of this next and the next of the next ... |
||
| 7 | |||
| 8 | first element next |
||
| 9 | first element next |
||
| 10 | first element next |
||
| 11 | first element next |
||
| 12 | nil |
||
| 13 | |||
| 14 | The last element is **always** nil : this is the end of our list. |
||
| 15 | |||
| 16 | Example : 0 1 2 3 4 5 6 7 |
||
| 17 | |||
| 18 | 0 next |
||
| 19 | 1 next |
||
| 20 | 2 next |
||
| 21 | 3 next |
||
| 22 | 4 next |
||
| 23 | 5 next |
||
| 24 | 6 next |
||
| 25 | 7 nil |
||
| 26 | |||
| 27 | So, we get in Scol : |
||
| 28 | |||
| 29 | <pre> |
||
| 30 | [0 next] with next is [1 next_2] with next_2 is [2 next_3] .... until [7 nil] |
||
| 31 | </pre> |
||
| 32 | |||
| 33 | So, we get really in Scol : |
||
| 34 | |||
| 35 | <pre> |
||
| 36 | [0 [1 [2 [3 [4 [5 [6 [7 nil]]]]]]]] |
||
| 37 | </pre> |
||
| 38 | |||
| 39 | We can write the same exact list with this other manner : |
||
| 40 | |||
| 41 | <pre> |
||
| 42 | 0::1::2::3::4::5::6::7::nil |
||
| 43 | </pre> |
||
| 44 | This is faster but the structure disappears. |
||
| 45 | |||
| 46 | *hd* <list> returns the first element (head) |
||
| 47 | *tl* <list> returns the next (tail) |
||
| 48 | |||
| 49 | h2. What is the type of a list ? |
||
| 50 | |||
| 51 | Generally, the type of a list is *[u0 r1]*, u0 for any type, simple or complex, r1 for the first level of recursivity. The second level, r2, exists, rarest. r3 ... rn are theoretical. |
||
| 52 | |||
| 53 | h3. Example : |
||
| 54 | |||
| 55 | *[I r1]* : a list of integers |
||
| 56 | *[[S F] r1]* : a list of tuple, each tuple has two element, a string (F) and a float (F) |
||
| 57 | *[[[[S I I] r1] I S] r1]* : a list of tuples, each tuple has three elements : another list, an integer, a string. |
||
| 58 | *[[S r1] r1]* : a list of list of strings. We will meet often this when we parse a text : each line is a list of words, the text is a list of lines. |
||
| 59 | |||
| 60 | h2. How get the Nth element ? |
||
| 61 | |||
| 62 | h3. By a Scol function (standard api) : |
||
| 63 | |||
| 64 | *nth_list* <list> <position> |
||
| 65 | |||
| 66 | <pre> |
||
| 67 | |||
| 68 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 69 | set n = nth_list list 5; // is 54 |
||
| 70 | </pre> |
||
| 71 | |||
| 72 | h3. By writing a recursive function. |
||
| 73 | |||
| 74 | We find again the structure of a list : |
||
| 75 | |||
| 76 | <pre> |
||
| 77 | fun getNelement (list, n)= |
||
| 78 | if list == nil then |
||
| 79 | nil // the list is smaller then n |
||
| 80 | else |
||
| 81 | let list -> [first next] in |
||
| 82 | if n == 0 then |
||
| 83 | first |
||
| 84 | else |
||
| 85 | getNelement next n-1;; // we continue with the next of the current list |
||
| 86 | |||
| 87 | fun main ()= |
||
| 88 | _showconsole; |
||
| 89 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 90 | _fooId getNelement list 5; // 54 is displayed |
||
| 91 | 0;; |
||
| 92 | </pre> |
||
| 93 | |||
| 94 | Note : the list is unchanged before and after the threatment by getNelement ! |
||
| 95 | |||
| 96 | h2. How get the size of a list ? |
||
| 97 | |||
| 98 | h3. By a Scol function (standard api) : |
||
| 99 | |||
| 100 | *sizelist* <list> |
||
| 101 | |||
| 102 | <pre> |
||
| 103 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 104 | set size = sizelist list; // is 8 |
||
| 105 | </pre> |
||
| 106 | |||
| 107 | h3. By writing a recursive function. |
||
| 108 | |||
| 109 | We find again the structure of a list : |
||
| 110 | |||
| 111 | <pre> |
||
| 112 | fun getSizeList (list, n)= |
||
| 113 | if list == nil then |
||
| 114 | n // we are at the end of the list (= nil) |
||
| 115 | else |
||
| 116 | getSizeList tl list n+1;; // we continue with the next of the current list |
||
| 117 | |||
| 118 | fun main ()= |
||
| 119 | _showconsole; |
||
| 120 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 121 | _fooId getSizeList list 0; // 8 is displayed |
||
| 122 | 0;; |
||
| 123 | </pre> |
||
| 124 | |||
| 125 | h2. How set the Nth element ? |
||
| 126 | |||
| 127 | By writing a recursive function. We find again the structure of a list : |
||
| 128 | |||
| 129 | <pre> |
||
| 130 | fun setNelement (list, position, value)= |
||
| 131 | if list == nil then |
||
| 132 | nil // the list is smaller then n |
||
| 133 | else |
||
| 134 | if position == 0 then |
||
| 135 | [value tl list] // or value :: (tl list), it is the same thing |
||
| 136 | else |
||
| 137 | [hd list setNelement tl list position-1 value];; // we continue with the next of the current list |
||
| 138 | |||
| 139 | fun main ()= |
||
| 140 | _showconsole; |
||
| 141 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 142 | set list = setNelement list 5 100; // [0 [10 [21 [32 [43 [100 [65 [76 nil]]]]]]]] |
||
| 143 | 0;; |
||
| 144 | </pre> |
||
| 145 | |||
| 146 | h2. How to get a sub list from a position ? |
||
| 147 | |||
| 148 | By writing a recursive function. We find again the structure of a list : |
||
| 149 | |||
| 150 | <pre> |
||
| 151 | fun getSubList (list, position)= |
||
| 152 | if list == nil then |
||
| 153 | nil // the list is smaller then n |
||
| 154 | else |
||
| 155 | if position == 0 then |
||
| 156 | list |
||
| 157 | else |
||
| 158 | getSubList tl list position-1;; // we continue with the next of the current list |
||
| 159 | |||
| 160 | fun main ()= |
||
| 161 | _showconsole; |
||
| 162 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 163 | set list = getSubList list 5; // [54 [65 [76 nil]]] |
||
| 164 | 0;; |
||
| 165 | </pre> |
||
| 166 | |||
| 167 | h2. How to find the position of an element ? |
||
| 168 | |||
| 169 | By writing a recursive function. We find again the structure of a list : |
||
| 170 | |||
| 171 | <pre> |
||
| 172 | fun findAnInteger (list, intToFind, position)= // all types except a string (S) |
||
| 173 | if list == nil then |
||
| 174 | nil // not found |
||
| 175 | else |
||
| 176 | if intToFind == hd list then |
||
| 177 | position |
||
| 178 | else |
||
| 179 | findAnInteger tl list intToFind position+1;; // we continue with the next of the current list |
||
| 180 | |||
| 181 | fun findAString (list, strToFind, position)= // type string (S) only |
||
| 182 | if list == nil then |
||
| 183 | nil // not found |
||
| 184 | else |
||
| 185 | if (!strcmp strToFind hd list )then |
||
| 186 | position |
||
| 187 | else |
||
| 188 | findAString tl list strToFind position+1;; // we continue with the next of the current list |
||
| 189 | |||
| 190 | fun main ()= |
||
| 191 | _showconsole; |
||
| 192 | set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 193 | _fooId findAnInteger list 54 0; // 5 |
||
| 194 | 0;; |
||
| 195 | </pre> |
||
| 196 | |||
| 197 | h2. How compare two lists ? |
||
| 198 | |||
| 199 | By writing a recursive function. We find again the structure of a list : |
||
| 200 | |||
| 201 | <pre> |
||
| 202 | fun cmpLists (listA, listB)= |
||
| 203 | if ((listA == nil) && (listB == nil)) then // lists are ended, we return 1 (true) |
||
| 204 | 1 |
||
| 205 | else if (hd listA) == (hd listB) then // First elements are equals, we continue with the next |
||
| 206 | cmpLists tl listA tl listB |
||
| 207 | else // first elements ae differents, we stop and returns 0 (false) |
||
| 208 | 0;; |
||
| 209 | |||
| 210 | fun main ()= |
||
| 211 | _showconsole; |
||
| 212 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 213 | set listB = [0 [10 [21 [32 [43 [54 [65 nil]]]]]]]; |
||
| 214 | _fooId cmpLists listA listB; // 0, not equal |
||
| 215 | 0;; |
||
| 216 | </pre> |
||
| 217 | |||
| 218 | --------------------- |
||
| 219 | |||
| 220 | To try it, copy this code : |
||
| 221 | |||
| 222 | - In _tutorials/list.pkg_ : |
||
| 223 | |||
| 224 | <pre> |
||
| 225 | typeof listA = [I r1];; |
||
| 226 | typeof listB = [I r1];; |
||
| 227 | |||
| 228 | fun getNelement (list, n)= |
||
| 229 | if list == nil then |
||
| 230 | nil // the list is smaller then n |
||
| 231 | else |
||
| 232 | let list -> [first next] in |
||
| 233 | if n == 0 then |
||
| 234 | first |
||
| 235 | else |
||
| 236 | getNelement next n-1;; // we continue with the next of the current list |
||
| 237 | |||
| 238 | fun mainGetNelement ()= |
||
| 239 | _showconsole; |
||
| 240 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 241 | _fooId getNelement listA 5; // 54 is displayed |
||
| 242 | 0;; |
||
| 243 | |||
| 244 | fun getSizeList (list, n)= |
||
| 245 | if list == nil then |
||
| 246 | n // we are at the end of the list (= nil) |
||
| 247 | else |
||
| 248 | getSizeList tl list n+1;; // we continue with the next of the current list |
||
| 249 | |||
| 250 | fun mainSizeList ()= |
||
| 251 | _showconsole; |
||
| 252 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 253 | _fooId getSizeList listA 0; // 8 is displayed |
||
| 254 | 0;; |
||
| 255 | |||
| 256 | fun setNelement (list, position, value)= |
||
| 257 | if list == nil then |
||
| 258 | nil // the list is smaller then n |
||
| 259 | else |
||
| 260 | if position == 0 then |
||
| 261 | [value tl list] // or value :: (tl list), it is the same thing |
||
| 262 | else |
||
| 263 | [hd list setNelement tl list position-1 value];; // we continue with the next of the current list |
||
| 264 | |||
| 265 | fun mainSetNelement ()= |
||
| 266 | _showconsole; |
||
| 267 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 268 | set listA = setNelement listA 5 100; // [0 [10 [21 [32 [43 [100 [65 [76 nil]]]]]]]] |
||
| 269 | _fooIdList listA; |
||
| 270 | 0;; |
||
| 271 | |||
| 272 | fun getSubList (list, position)= |
||
| 273 | if list == nil then |
||
| 274 | nil // the list is smaller then n |
||
| 275 | else |
||
| 276 | if position == 0 then |
||
| 277 | list |
||
| 278 | else |
||
| 279 | getSubList tl list position-1;; // we continue with the next of the current list |
||
| 280 | |||
| 281 | fun mainSubList ()= |
||
| 282 | _showconsole; |
||
| 283 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 284 | set listA = getSubList listA 5; // [54 [65 [76 nil]]] |
||
| 285 | _fooIdList listA; |
||
| 286 | 0;; |
||
| 287 | |||
| 288 | fun findAnInteger (list, intToFind, position)= // all types except a string (S) |
||
| 289 | if list == nil then |
||
| 290 | nil // not found |
||
| 291 | else |
||
| 292 | if intToFind == hd list then |
||
| 293 | position |
||
| 294 | else |
||
| 295 | findAnInteger tl list intToFind position+1;; // we continue with the next of the current list |
||
| 296 | |||
| 297 | fun findAString (list, strToFind, position)= // type string (S) only |
||
| 298 | if list == nil then |
||
| 299 | nil // not found |
||
| 300 | else |
||
| 301 | if (!strcmp strToFind hd list )then |
||
| 302 | position |
||
| 303 | else |
||
| 304 | findAString tl list strToFind position+1;; // we continue with the next of the current list |
||
| 305 | |||
| 306 | fun mainFind ()= |
||
| 307 | _showconsole; |
||
| 308 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 309 | _fooId findAnInteger listA 54 0; // 5 |
||
| 310 | 0;; |
||
| 311 | |||
| 312 | fun cmpLists (listA, listB)= |
||
| 313 | if ((listA == nil) && (listB == nil)) then // lists are ended, we return 1 (true) |
||
| 314 | 1 |
||
| 315 | else if (hd listA) == (hd listB) then // First elements are equals, we continue with the next |
||
| 316 | cmpLists tl listA tl listB |
||
| 317 | else // first elements ae differents, we stop and returns 0 (false) |
||
| 318 | 0;; |
||
| 319 | |||
| 320 | fun mainCmp ()= |
||
| 321 | _showconsole; |
||
| 322 | set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]]; |
||
| 323 | set listB = [0 [10 [21 [32 [43 [54 [65 nil]]]]]]]; |
||
| 324 | _fooId cmpLists listA listB; |
||
| 325 | 0;; |
||
| 326 | </pre> |
||
| 327 | |||
| 328 | - In _tutorials/list.scol_ : |
||
| 329 | |||
| 330 | <pre> |
||
| 331 | _load "tutorials/list.pkg" |
||
| 332 | mainGetNelement |
||
| 333 | mainSizeList |
||
| 334 | mainSetNelement |
||
| 335 | mainSubList |
||
| 336 | mainFind |
||
| 337 | mainCmp |
||
| 338 | </pre> |
||
| 339 | |||
| 340 | Note : |
||
| 341 | In files "locked/lib/stdlib.pkg" et "locked/lib/_mlistlib.pkg", functions about lists are already coded. For use them, add the line _load "locked/lib/stdlib.pkg" and(or) the line _load "locked/lib/_mlistlib.pkg" in your launcher. |
||
| 342 | |||
| 343 | Other functions about list are availables in the Syspack library. |
||
| 344 | |||
| 345 | |||
| 346 | License : "CC-BY-SA-2.0":https://creativecommons.org/licenses/by-sa/2.0/ |
||
| 347 | Tutorial by iri |
||
| 348 | Updated by / |