Applies To: CitectSCADA v5.x, v6.x, v7.x

 Summary: How can you efficiently search an array to find the location of a certain item in it?

 Solution: The TableLookup() Cicode function can be used to search an array. Unfortunately, it only works for arrays of REAL (floating point) values. For INT or STRING arrays, custom Cicode will be needed. The simplest method is to use a FOR loop to check each element in the array and compare it with the desired value. This can be done with the linear search code below: ```//Searches gsSortArray for the sFind text and returns its element //number (between nFirst and nLast) or -1 if it was not found INT FUNCTION LinearSearch(STRING sFind, INT nFirst = 0, INT nLast = 478) INT nItem; FOR nItem = nFirst TO nLast DO IF sFind = gsSortArray[nItem] THEN RETURN nItem; END END RETURN -1; END ``` If the list is sorted (in alphabetical or numeric order--see Q3750), it is much faster to use the binary search method. This algorithm looks at the middle item in the list. If it is greater than the item to find, the search is repeated on the first half of the list, otherwise the 2nd half of the list is checked. Each time the list is cut in half until only the desired item remains (or no item remains if the search item doesn't exist). With a linear search of 100 items, on average half of the items will be checked before a match is found and all items must be checked if there is no match. With a binary search of 100 items only 6 or 7 items will need to be checked. Since binary search requires that the list is sorted, it may not be the best choice if the list is constantly changing. Having to re-sort the list each time will cancel out the benefit of Binary Search. Although this binary search function is for strings, it can be used for numbers simply by changing the STRING variables to REAL or INT. ```GLOBAL STRING gsSortArray[479]; //Contains sorted list of strings to search ``` ```// Search an ordered array for the first occurrence of the specified element // using the binary search algorithm. The element must match sFind exactly // to be successful (but case is ignored) // // Arguments: sFind Text to find // nFirst First element to search (normally 0) // nLast Last element to search (max 478 for strings) // // Returns the element number if successful, or -1 if the element was not found // // Note: 1. All elements in gsSortArray must be in alphabetical order // 2. If nFirst or nLast are outside of the array's bounds, a hardware // alarm is generated // 3. If the array has any blank elements, they must be before nFirst or // after nLast // INT FUNCTION BinarySearch(STRING sFind, INT nFirst = 0, INT nLast = 478) INT nMiddle, nHigh = nLast + 1, nLow = nFirst - 1; ``` ``` WHILE (nHigh - nLow) > 1 DO nMiddle = nLow + ((nHigh - nLow) / 2); IF gsSortArray[nMiddle] < sFind THEN nLow = nMiddle; ELSE nHigh = nMiddle; END END ``` ``` IF (nHigh = nLast + 1) THEN RETURN -1; ELSE IF (gsSortArray[nHigh] <> sFind) THEN RETURN -1; ELSE RETURN nHigh; END END END ```

 Keywords: