[Closed] find array index
Hello!
I am writing a script that will animate an object based on its distance to another objects position. I am using the distance from the target object (dummy) as the start frame.
This works great if I am animating boxes that are all uniformly spaced. In the real world though I have objects spread out over “miles” so, I am putting all of the objects distance values into an array and then sorting that array. I would like to use the array index as the start frame. Is there a way I can quickly collect the array index? Here is some example code:
theArr=#(30,2,54,77,565,433,5,3,866)
sort theArr
for n = 1 to theArr.count do
(
theArrValue = theArr(n).index
print theArrValue as string
)
I realize that “n” IS the index, however the names of the objects are duplicates in many cases. I was writing a function that collected an array with the object name and distance value and then doing a filterstring to find that value in the original array and find the index that way but it seemed like the WAY WRONG way to do it. So many words for such a seemingly simple thing…I am shamed. :hmm:
looks like findItem is a good way to achieve this. Not the result I was looking for though.
Take a look at qsort() in the Help, and specifically at the example of Indexed Sorting.
Basically you collect one array with the objects, another array with the distances, and an index array with the indices from 1 to N before sorting. Then you sort the index array using the distance array as data array (the former is being reordered based on whether the corresponding distance values are greater or less). Once the qsort is done, the index array is in the desired order and you can simply go to any element of the index array and use its value to grab the corresponding object by index. For example, to get the 3rd closest object, get the 3rd element of the index array, let’s call it ‘theIndex’. Then theObjects[theIndex] will give you the object that is 3rd closest, and theDistances[theIndex] will give you the corresponding distance.
Here is an example;-)
struct DUMMY_DATA (name, dist) -- or (handle, dist)
fn compareFN v1 v2 =
(
local d = v1.dist - v2.dist
case of
(
(d < 0.): -1
(d > 0.): 1
default: 0
)
)
arr = for i=1 to 10 collect DUMMY_DATA name:("n_" + i as string) dist:(random 1 100)
format "struct array:%
" arr
--struct array:#((DUMMY_DATA name:"n_1" Dist:28), (DUMMY_DATA name:"n_2" Dist:3), (DUMMY_DATA name:"n_3" Dist:11) ..
qsort arr compareFN
format "struct array:%
" arr
--struct array:#((DUMMY_DATA name:"n_9" Dist:2), (DUMMY_DATA name:"n_4" Dist:5), (DUMMY_DATA name:"n_1" Dist:12) ..
Thank you Bobo and Merlin!
I have seen qsort before but didn’t fully understand it. Now that I see it, I see that it is exactly what I need. Thanks!