finding an array element

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

finding an array element

Post by sp27 » Fri May 13, 2011 9:23 pm

Given this array:

put 15 into myArr[1]
put 16 into myArr[2]
put 17 into myArr[3]

how do I find the position of 16 in that array (which is 2)?

I know I can loop through the array looking for 16, but there's probably a more efficient way...

Slava

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9580
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: finding an array element

Post by dunbarx » Fri May 13, 2011 10:51 pm

Try this:

Code: Select all

on mouseUp
put 15 into myArr[1]
put 16 into myArr[2]
put 17 into myArr[3]

combine myArr by return and comma
answer myArr

end mouseUp

This should get you started,

Craig Newman

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

Re: finding an array element

Post by sp27 » Sat May 14, 2011 1:05 am

Thanks, Craig, but that's not what I asked.

The handler you kindly suggested lists the contents of the array.

I am looking for a way to determine the position of an element with a certain value. E.g., the value of the second element is 16. I want a function like myArr.getPos(16) that would return 2.

I couldn't find the answer in the section on arrays in the User Guide, and all the terms I tried to look up in the Dictionary turned out to be bad guesses. With the English-like synatx of LC, I don't know what to look for.

I can probably write my own function along the lines of

Code: Select all

function getPos aArr, aVal
repeat with i = 1 to the number of elements in aArr
if aArr[i] is aVal then
return i
end if
end repeat
end getPos
but that would hardly be efficient. I'm sure the language has what I'm looking for... doesn't it?

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: finding an array element

Post by Mark » Sat May 14, 2011 1:23 am

Craig was pretty close:

Code: Select all

on mouseUp
  put 15 into myArr[1]
  put 16 into myArr[2]
  put 17 into myArr[3]
  combine myArr by cr and comma
  sort lines of myArr by (item 2 of each is 16)
  put item 1 of last line of myArr into myPos
  answer myPos
end mouseUp
I'm not saying that this is efficient. For more complex searches, you'll have to replace (item 2 of each is 16) with a custom function. This might make it rather slow. Looping through all elements of the array might be faster, depending on the complexity of the search.

Kind regards,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

Re: finding an array element

Post by sp27 » Sat May 14, 2011 1:48 am

Thanks, Mark. I can't believe the language has no built-in function to find an element in an array by its value. Every other language I know does. Perhaps I am on the wrong track altogether, and an array is simply not used for that kind of thing in LC?

Suppose you have two lists of values, and you need a conversion routine. Let's say you are building your own function for converting upper case characters to lower case. You have 32,000 pairs of letters. For examle, you know that the character whose decimal code point is 1234 happens to be the upper case leetter for the character whose decimal code point is 1268. You have two decimal numbers for each upper case/lower case pair.

One way to do that is to set two arrays such that element N of array UpperCaceArr is the upper case equivalent of element N of array LowerCaseArr. Then, given any character's code point you can find its position in one of these arrays, and presto! the corresponding element of the other array is its upper/lower case equivalent.

There are countless situations where the ability to find the position of a certain value within an array is useful. If arrays in LC aren't built for those operations, then what is?

Slava

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Re: finding an array element

Post by Mark » Sat May 14, 2011 10:01 am

Hi Slava,

If you have two corresponding lists of values, you'd save them as separate lists. Get the lineoffset of a value in one list and find the line with that lineoffset in the second list. Let's assume you keep the two lists of characters in fields.

put line lineoffset(myChar,fld "List 1") of fld "List 2" into myNewChar

No arrays involved.

Kind regars,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

Re: finding an array element

Post by sp27 » Sat May 14, 2011 1:23 pm

Thanks, Mark. You've been very helpful. So you're assuming I have my 32,000 decimal numbers in a text field, one number per line, and lineoffset() will search that text field. I was thinking that an array of integers would be more efficient, but I'll experiment with this. I don't really needs 32,000 numbers, that was only an example. And I didn't know enough to think of lineoffset.

Thanks also for your response to my Unicode question. I'll exsperiment with that, and I'm sure I'll have more postings on Unicode.

Perhaps I should explain what I am doing and why I'm in the summer academy, learning CL.

I am porting my Adobe Director application. It is a Russian dictionary for students. The data is in a SQLite database. The student will run searches and view the entries--that's it. Very simple. The db has a look-up index table where each word points to an entry in another table. 250,000 records in the lookup table, and 17,000 records in the entries table. All entries are stored as fairly simple HTML, for easy display and formatting. Cyrillic characters are stored as UTF-8 text, not as HTML entities.

So my first CL application has to:

1) accept user's input, a typed string;

2) the user will be typing with her English keyboard, so before displaying what she types in Cyrilic, the field must remap the keyboard input, e.g. when the user types the English lower case "a" the field must receive and display the Russian "a" which is 1072 decimal in Unicode;

3) because the user might type punctuation, upper and lower case letters, and accented letters, the CL script must normalize the input, i.e. remove all illegal characters and convert upper case and accented letters to their lowwer case unaccented equivalents. The normalized string need not be displayed.

4) look up the normalized string in the look-up table (i. e. run a SELECT query)

5) retrieve the matching enrties from the other table; they are in HTML format, full of Unicode Cyrillic and English text

6) display the HTML by assigning it to a field.

I am trying to learn how to do this. Since I've already done it in Director, I'm probably going through a very convoluted learning curve :)

Gratefully,

Slava

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7215
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: finding an array element

Post by jacque » Sun May 15, 2011 8:09 pm

There may be a crafty way to do what you want, but I think you'll be surprised at just how fast "repeat for each" really is. It can easily process tens of thousands of items in a few milliseconds. In fact, it's so fast that it is usually the preferred way -- it beats out a number of other methods in most benchmarking tests. I'd try benchmarking a "repeat for each" loop that iterates through all the array elements and see if it's fast enough for you.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

Re: finding an array element

Post by sp27 » Mon May 16, 2011 4:33 am

In his May 14 response, Mark said:
If you have two corresponding lists of values, you'd save them as separate lists. Get the lineoffset of a value in one list and find the line with that lineoffset in the second list. Let's assume you keep the two lists of characters in fields.

put line lineoffset(myChar,fld "List 1") of fld "List 2" into myNewChar
I think Mark overlooked my assignment: the two lists (I wanted arrays, but Mark suggested lists) hold the decimal code points of the alphabetic characters, not the characters themselves. If List 1 starts like this:

1073
1046
1024
986
106
104
etc.

and the decimal point of myChar happens to be 104, then lineoffset(myChar,fld "List 1") will return 2, because everything is a string, and all comparisons are by text chunks, and "104" is part of string "1046," which is in line 2. The correct value should be 6, because 104 is on the sixths line.

If using this method, I would have to look for the lineoffset by matching the entire line to my target, not a portion of it. If we dealt with numbers instead of strings (in an array or a list), 1046 would not be considered a match for 104.

Is there a way to achieve that?

Thanks,

Slava

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

Re: finding an array element

Post by sp27 » Mon May 16, 2011 5:25 am

After some benchmarking, as jacque suggested, I think the "repeat for each" loop through the entire list of numbers is very practical. Thanks, everybody!

Slava

Regulae
Posts: 136
Joined: Tue Oct 20, 2009 6:05 am
Location: Australia

Re: finding an array element

Post by Regulae » Mon May 16, 2011 6:30 am

Hi there,

You may have already found this, but it's worth mentioning- setting the wholeMatches to true achieves the whole line matching you want. From the dictionary, wholeMatches:
Summary:
Specifies whether the lineOffset, wordOffset, and itemOffset functions search only for entire lines, words, or items.

Examples:
set the wholeMatches to true


Use the wholeMatches property to find lines, words, or items in a container only if what you're searching for matches an entire line, word, or item.
Regards,
Michael

sp27
Posts: 135
Joined: Mon May 09, 2011 3:01 pm

Re: finding an array element

Post by sp27 » Mon May 16, 2011 7:32 am

Thanks, Michael! Yes, this works great, too. S.

laouris
Posts: 5
Joined: Sun Nov 13, 2016 1:46 pm

Re: finding an array element

Post by laouris » Tue Mar 22, 2022 6:54 pm

Here is the function and a working example for finding the position (key) of an element with a certain value in a 2D Array.

The code:

function getPosOfValueInArray aArr, aVal
repeat with i = 1 to the number of lines in the keys of aArr
if aArr["Idea ID"] = aVal then
return i
end if
end repeat
end getPosOfValueInArray


You may wish to use a parameter for the name of the column: "Idea ID" eg aHeading:
Attachments
Find Position Of Value In 2D Array.livecode.zip
(5.98 KiB) Downloaded 86 times

Klaus
Posts: 13806
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: finding an array element

Post by Klaus » Tue Mar 22, 2022 7:37 pm

Better late than never, right? :D

stam
Posts: 2635
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: finding an array element

Post by stam » Tue Mar 22, 2022 8:26 pm

Yes yes, late is fine ;)
Good for people learning!

Although i'm surprised no one mentioned the filter option for doing this - much easier and simpler.

Code: Select all

function findIndexOfElementContaining pValue, pArray
    filter elements of pArray where each = pValue
    return the keys of pArray
end findIndexOfElementContaining
Calling

Code: Select all

put findIndexOfElementContaining(16, myArr)
will put '2' in the message box, as per the OP. If there are multiple keys containing this value, it will return a return-delimited list.

I really do love using filter for arrays - the 'each' keyword is the special sauce... no need for messy iterations ;)

Stam

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”