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