Monday, May 25, 2020

#1 2020-05-22 11:08:18 am

mcsprodart
Member
Registered: 2013-03-09
Posts: 9

Filter Array

Trying to figure out best filter process for a list of lists using ApplescriptObjC

I have an array of 2600+ lists and want to filter out the ones with "I" in item 31 of each.

I tried using this Nigel Garvey snippet and it Is returning the incorrect results. Im sure its meant for a string and not list. Repeat loops are just too slow using standard AppleScript.

Applescript:



on itemsWithout:theVal inList:theListofLists
   set theArray to current application's NSArray's arrayWithArray:theListofLists
   set thePred to current application's NSPredicate's predicateWithFormat:"NOT (self CONTAINS %@)" argumentArray:{theVal}
   return (theArray's filteredArrayUsingPredicate:thePred) as list
end itemsWithout:inList:

on a separate note, does anyone know of a good location that documents the options for predicateWithFormat?

Thanks

Offline

 

#2 2020-05-22 05:44:45 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5202

Re: Filter Array

mcsprodart wrote:

I tried using this Nigel Garvey snippet and it Is returning the incorrect results. Im sure its meant for a string and not list.


It's meant to filter a list of lists for lists not containing a certain value:

Applescript:

set lst to {{1, 2, 3}, {4, 5, 6}, {9, 7, 5}}
my itemsWithout:4 inList:lst
--> {"1 2 3", "9 7 5"}

But it does work for filtering a list of texts for those not containing a certain substring.

I can't think how you'd filter for what you want without using a repeat. It's not actually as slow with that many lists as you might think:

Applescript:

on listsWithout:theSubstring inItem:idx inList:listOfLists
   script o
       property mainList : listOfLists
       property filteredList : {}
   end script
   
   repeat with i from 1 to (count listOfLists)
       set thisItem to item i of o's mainList
       if (item idx of thisItem does not contain theSubstring) then set end of o's filteredList to thisItem
   end repeat
   return o's filteredList
end itemsWithout:inItem:inList:

-- Set up a list containing 2700 35-item lists, the 31st item in each
-- being a string which may or may not contain "l".
set template to {}
repeat with i from 1 to 35
   set end of template to missing value
end repeat

set aList to {}
repeat 2700 times
   set tmplt to my template's items
   set item 31 of my tmplt to some item of {"aardvark", "plunge", "parallel", "banana"}
   set end of my aList to tmplt
end repeat

-- Announce the beginning and end of the filtering operation.
say "Filtering…"
set filteredList to my listsWithout:"l" inItem:31 inList:aList
say "Done. The filtered list contains " & (count filteredList) & "items out of the original 2700."

mcsprodart wrote:

on a separate note, does anyone know of a good location that documents the options for predicateWithFormat?


https://developer.apple.com/library/arc … TP40001789


NG

Offline

 

#3 2020-05-22 07:18:39 pm

mcsprodart
Member
Registered: 2013-03-09
Posts: 9

Re: Filter Array

Thank you!
I appreciate your response. I thought someone would be pushing me to a predicateWithFormat inside a predicate or something. predicate seems like voodoo witchcraft but not necessarily in a bad way.

Your as always "The Man" or you may prefer "The Dude".

Last edited by mcsprodart (2020-05-22 07:22:09 pm)

Offline

 

#4 2020-05-22 08:35:29 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6362

Re: Filter Array

This should do what you want:

Applescript:

use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions

set theListOfLists to {{"a", "b", "c"}, {"g", "l", "k"}, {"a", "b", "d"}, {"a", "l", "c"}}
set theArray to current application's NSArray's arrayWithArray:theListOfLists
set thePred to current application's NSPredicate's predicateWithFormat:"NOT (self[1] CONTAINS %@)" argumentArray:{"l"}
return (theArray's filteredArrayUsingPredicate:thePred) as list

Just remember the index is zero-based, so you'd use self[30].

Last edited by Shane Stanley (2020-05-22 08:36:54 pm)


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Offline

 

#5 2020-05-22 09:17:57 pm

mcsprodart
Member
Registered: 2013-03-09
Posts: 9

Re: Filter Array

Nigel,
You were right it wasn’t that much of a slowdown. It's a lot faster in your subroutine then in the main script as I put it. 8.35 seconds Mine was like 30 seconds.

Just curious. Something I get when testing your code here and the previous code you posted in your sorting library, both give me table overflow errors when in debugging mode. I think it has something to do with property being used in the subroutine. Any thoughts?

Shane - 7.36 seconds Thanks for clarifying….always close but never obvious on the index. I tried at some point but never would have tried starting with 0.

Offline

 

#6 Yesterday 02:28:50 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5202

Re: Filter Array

mcsprodart wrote:

Nigel,
… Something I get when testing your code here and the previous code you posted in your sorting library, both give me table overflow errors when in debugging mode. I think it has something to do with property being used in the subroutine. Any thoughts?


Debugging mode is a peculiarity of Script Debugger. I take no responsibility for it.  wink


NG

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)