.. index:: 
	single: Lists; Introduction

=====
Lists
=====

In this chapter we are going to learn how to deal with lists.

.. index:: 
	pair: Lists; Create Lists

Create Lists
============

We can create new lists by defining the list items inside square bracts.

Example:

.. code-block:: ring

	aList = [1,2,3,4,5]

Also we can create new lists using the : operator


Example:

.. code-block:: ring

	aList = 1:5
	aList2 = "a":"z"

Example:

.. code-block:: ring

	aList = 5:1
	aList2 = "z":"a"

Also we can create lists using the list() function

Syntax:

.. code-block:: ring

	list = list(size)

Example

.. code-block:: ring

	aList = list(10)	# aList contains 10 items

.. note:: the list index start from 1 

.. index:: 
	pair: Lists; Add Items

Add Items
=========

To add new items to the list, we can use the Add() function.

Syntax:

.. code-block:: ring

	Add(List,Item)


Example:

.. code-block:: ring

	aList = ["one","two"]
	add(aList,"three")
	see aList

Also we can do that using the + operator.

Syntax:

.. code-block:: ring

	List + item

Example:

.. code-block:: ring

	aList = 1:10	# create list contains numbers from 1 to 10
	aList + 11	# add number 11 to the list
	see aList	# print the list

.. index:: 
	pair: Lists; Get List Size

Get List Size
=============

We can get the list size using the len() function

Syntax:

.. code-block:: ring

	Len(List)

Example:

.. code-block:: ring

	aList = 1:20  see len(aList)  # print 20

.. index:: 
	pair: Lists; Delete Item From List

Delete Item From List
=====================

To delete an item from the list, we can use the del() function

Syntax:

.. code-block:: ring

	del(list,index)

Example:

.. code-block:: ring

	aList = ["one","two","other","three"]
	Del(aList,3)	# delete item number three
	see aList   	# print one two three


.. index:: 
	pair: Lists; Get List Item
	
Get List Item
=============

To get an item from the list, we uses the next syntax

.. code-block:: ring

	List[Index]

Example:

.. code-block:: ring

	aList = ["Cairo","Riyadh"]
	see "Egypt : " + aList[1] + nl +
	    "KSA   : " + aList[2] + nl

.. index:: 
	pair: Lists; Set List Item

Set List Item
=============

To set the value of an item inside the list, we can use the next syntax

.. code-block:: ring

	List[Index] = Expression

Example:

.. code-block:: ring

	aList = list(3)	# create list contains three items
	aList[1] = "one" aList[2] = "two" aList[3] = "three"
	see aList

.. index:: 
	pair: Lists; Search

Search
======

To find an item inside the list we can use the find() function

Syntax:

.. code-block:: ring

	Find(List,ItemValue) ---> Item Index
	Find(List,ItemValue,nColumn) ---> Search in nColumn, returns the Item Index 
	Find(List,ItemValue,nColumn,cAttribute) ---> Item Index

Example:

.. code-block:: ring

	aList = ["one","two","three","four","five"]
	see find(aList,"three")		# print 3

Example:

.. code-block:: ring

	mylist = [["one",1],
		  ["two",2],
		  ["three",3]]

	see find(mylist,"two",1) + nl		# print 2
	see find(mylist,2,2) + nl		# print 2

Also we can use the binarysearch() function to search in sorted list.

Syntax:

.. code-block:: ring

	BinarySearch(List,ItemValue) ---> Item Index
	BinarySearch(List,ItemValue,nColumn) ---> Search in nColumn, returns the Item Index 

Example:

.. code-block:: ring

	aList = ["one","two","three","four","five"]
	aList = sort(aList)
	see binarysearch(aList,"three")

Output:

.. code-block:: ring

	five
	four
	one
	three
	two
	4

.. index:: 
	pair: Lists; Sort()

Sort
====

We can sort the list using the sort() function.

Syntax:

.. code-block:: ring

	Sort(List) ---> Sorted List
	Sort(List,nColumn) ---> Sorted List based on nColumn 
	Sort(List,nColumn,cAttribute) ---> Sorted List based on Object Attribute

Example:

.. code-block:: ring

	aList = [10,12,3,5,31,15]
	aList = sort(aList) see aList # print 3 5 10 12 15 31

We can sort list of strings

Example:

.. code-block:: ring

	mylist = ["mahmoud","samir","ahmed","ibrahim","mohammed"]
	see mylist	   	  # print list before sorting
	mylist = sort(mylist)	  # sort list
	see "list after sort"+nl
	see mylist		  # print ahmed ibrahim mahmoud mohammed samir

We can sort a list based on a specific column.

Example:

.. code-block:: ring

	aList = [ ["mahmoud",15000] ,
		  ["ahmed", 14000 ] ,
		  ["samir", 16000 ] ,
		  ["mohammed", 12000 ] ,
	 	  ["ibrahim",11000 ] ]

	aList2 = sort(aList,1)
	see aList2

Output:

.. code-block:: ring

	ahmed
	14000
	ibrahim
	11000
	mahmoud
	15000
	mohammed
	12000
	samir
	16000


.. index:: 
	pair: Lists; Reverse()

Reverse
=======

We can reverse a list using the reverse() function.

Syntax:

.. code-block:: ring

	Reverse(List) ---> Reversed List

Example:

.. code-block:: ring

	aList = [10,20,30,40,50]
	aList = reverse(aList)
	see aList 	# print 50 40 30 20 10

.. index:: 
	pair: Lists; Insert()

Insert Items
============

To insert an item in the list we can use the insert() function.

Syntax:

.. code-block:: ring

	Insert(List,Index,Item)

The inserted item will be AFTER the Index

Example:

.. code-block:: ring

	aList = ["A","B","D","E"]
	insert(aList,2,"C")    # Inserts AFTER Index 2, "C" into Position 3
	see aList              # print A B C D E


.. index:: 
	pair: Lists; Nested Lists

Nested Lists
============

The list may contain other lists

Example:

.. code-block:: ring

	aList = [ 1 , [10,20,30] , 5 , [100,1000,5000] ]
	aList2 = [
	"one","two", 
	[3,4],
	[20,30], ["three",
		  "four",
		  "five",[100,200,300]
                 ]
	]
	
	see aList[2] 	 	# print 10 20 30
	see aList[4][3] + nl 	# print 5000
	see aList2[5][2] + nl 	# print four
	see aList2[5][4][3]	# print 300

.. index:: 
	pair: Lists; Copy Lists

Copy Lists
==========

We can copy lists (including nested lists) using the Assignment operator.

Example:

.. code-block:: ring

	aList = [
	"one","two", 
	[3,4],
	[20,30], ["three",
		  "four",
		  "five",[100,200,300]
                 ]
	]

	aList2 = aList		# Copy aList to aList2
	aList2[5] = "other"	# modify item number five
	see aList2[5] + nl	# print other
	see aList[5]		# print three four five 100 200 300


.. index:: 
	pair: Lists; First-Class Lists

First-class lists
=================

Lists are `first-class citizens <http://en.wikipedia.org/wiki/First-class_citizen>`_ where we can store
lists in variables, pass lists to functions, and return lists from functions.

Example:

.. code-block:: ring

	aList = duplicate( [1,2,3,4,5] )
	see aList[10] + nl		  # print 5

	see mylist()			  # print 10 20 30 40 50
	
	func duplicate list
		nMax = len(list)
		for x = 1 to nMax
			list + list[x]
		next
		return list

	func mylist return [10,20,30,40,50]

.. index:: 
	pair: Lists; Using Lists during definition
		
Using Lists during definition
=============================

We can use the list items while we are defining the list for the first time.

Example:

.. code-block:: ring

	aList = [ [1,2,3,4,5] , aList[1] , aList[1] ]
	see aList	# print 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
	
	
.. index:: 
	pair: Lists; Passing Lists to Functions

Passing Lists to Functions
==========================

Lists are passed to functions by reference, This means that the called
function will work on the same list and can modify it.

Example:

.. code-block:: ring

	func main
		aList = [1,2,3,4,5]	# create list, local in function main
		myfunc(aList)		# call function, pass list by reference
		see aList		# print 1 2 3 4 5 6 7 8 9 10

	func myfunc list
		list + [6,7,8,9,10]


.. index:: 
	pair: Lists; Access List Items by String Index

Access List Items by String Index
=================================

Instead of using numbers to determine the item index when we get item value or set item value,
We can access items using string index if the item is a list contains two items and 
the first item is a string.

Example:

.. code-block:: ring

	aList = [ ["one",1] , ["two",2] , ["three",3] ]
	see aList["one"] + nl +
	    aList["two"] + nl +
	    aList["three"] 	# print 1 2 3

This type of lists can be defined in a better syntax using the : and = operators.

Example:

.. code-block:: ring

	aList = [ :one = 1 , :two = 2 , :three = 3 ]
	see aList["one"] + nl +
	    aList["two"] + nl +
	    aList["three"] + nl	# print 1 2 3
	see aList[1]		# print one 1

.. tip:: using : before identifier (one word) means literal

.. note:: using = inside list definition create a list of two items where
	  the first item is the left side and the second item is the right side.

We can add new items to the list using the string index

Example:

.. code-block:: ring
	
	aList = []
	aList["Egypt"] = "Cairo"
	aList["KSA"] = "Riyadh"
	see aList["Egypt"] + nl + 	# print Cairo
	    aList["KSA"] + nl		# print Riyadh

.. index:: 
	pair: Lists; Passing Parameters or Arguments Using List

Passing Parameters or Arguments Using List
===========================================
	
This type of lists is very good for passing parameters to functions
Where the order of parameters will not be important (we can change the order).

Also some parameters maybe optional.

Example:

.. code-block:: ring

	myconnect (  [ :server = "myserver.com" , :port = 80 , 
                       :username = "mahmoud" , :password = "password" ] ) 

	func myconnect mypara
	
		# print connection details
		see "User Name : " + mypara[:username] + nl +
		    "Password  : " + mypara[:password] + nl +
                    "Server    : " + mypara[:server] + nl +
                    "Port      : " + mypara[:port]
.. index:: 
	pair: Lists; Passing Parameters Arguments Using List Array

Passing Parameters or Arguments Using List Array
=================================================
	
Passing Arguments or Parmameters to a Function in an array format

Example:

.. code-block:: ring

     myList = [5,7,3,9]    ### list with args or parms in  an array
     result = sum(myList)
     See "Sum result: "+ result +n

     func sum(aList)
       acc = 0
       sizeList = len(aList)
   
       for i = 1 to sizeList
          See aList[i] +nl
          acc = acc + aList[i]
       next
     return acc
 

.. index:: 
	pair: Lists; Return as List or Hash Table

Return Parameters as List or Hash Table
=======================================
	
Return Parameters from a Function in an Array or Hash Format

Example:

.. code-block:: ring

	sudoku = [  [2,9,0],
		    [0,0,1],
		    [0,0,0] ]

	aOutput = myFunctionArray(sudoku)
		See "Return Array: T/F: "+ aOutput[1] +" Row: "+ aOutput[2] +" Col: "+ aOutput[3] +nl

	aOutput = myFunctionHash(sudoku)
		See "Return Hash.: T/F: "+ aOutput[:lValue] +" Row: "+ aOutput[:nRow] +" Col: "+ aOutput[:nCol] +nl

	###----------------------------------
	### isSolvedSoduku - Return ARRAY

	Func myFunctionArray(sudoku)
	    for Row = 1 to 9
		for Col = 1 to 9
		    if sudoku[Row][Col] = 0

			//----------------------------
			// Return Array with 3 fields       
			return [False, Row, Col]                    
		    ok
		next
	    next
	return [True, Row, Col]

	###----------------------------------
	### isSolvedSoduku - Return HASH

	Func myFunctionHash(sudoku)
	    for Row = 1 to 3
		for Col = 1 to 3
		    if sudoku[Row][Col] = 0

			//---------------------------------
			// Return Hash Table with 3 fields      
			return  [   :lValue = False, 
				    :nRow   = Row, 
				    :nCol   = Col   
				]
		    ok
		next
	    next

	return  [ :lValue = False, :nRow = Row, :nCol = Col ]           

	###-----------------------------

     
.. index:: 
	pair: Lists; Create Multi Dimension Array  Using List and Recursion

Creating a Multi-Dimensional Array using  List
==============================================
	
A Multi-Dimensional Array of any size can be built using recursion in a  Function

Example:

.. code-block:: ring

        ###---------------------------------------------------------
        ### Create Array -- Dimensions Any Size:  3D, 4D, 5D etc

        dimList = [4,3,4]
        bList   = createDimList(dimList)
	
        ###---------------------------------------------------------
        ### Populate the arrays using a counter 1 ,  4x4x4 = 256 , 2x3x4x5x6 = 720

        Counter = 1

        for Col=1 to dimList[1]
          for Row=1 to dimList[2]
            for Dep=1 to dimList[3]
                    blist[Col][Row][Dep] = Counter
                    Counter++
            next
          next
        next

        ###-----------------------------------------------
        ### Print the array elements in block format

        for Col=1 to dimList[1]
          for Row=1 to dimList[2]
            for Dep=1 to dimList[3]
                    See bList[Col][Row][Dep] See " "
            next
	    See nl
          next
            See nl
        next

        ###===========================
        ### FUNCTIONS

        ###-----------------------------------------------------------------------
        ### Recursive Create a Dimension Array
        ### Call by passing an array of dimesions: dimList = [2,3,4,5]
        ### Drop the first entry every iteration call, making newParms
        ###
        ### Example:
        ###    dimList = [4,2,3,2]                <<< Number and size of dimensions in array format
        ###    bList   = createDimList(dimList)   <<< Call using the array as input

        func createDimList(dimArray)

             sizeList = len(dimArray)

             newParms = []
             for i = 2 to sizeList
                Add(newParms, dimArray[i])
             next

             alist = list(dimArray[1])

             if sizeList = 1
                return aList
             ok

             for t in alist
                 t = createDimList(newParms)
             next

        return alist
	
     
.. index:: 
	pair: Lists; Swap Items

Swap Items
==========

We can swap the list items using the Swap() function.

Example:

.. code-block:: ring

	aList = [:one,:two,:four,:three]
	see aList
	see copy("*",50) + nl
	swap(aList,3,4)
	see aList

Output

.. code-block:: ring

	one
	two
	four
	three
	**************************************************
	one
	two
	three
	four


