Wednesday, November 20, 2019

#1 2019-07-05 08:54:17 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3635

filter items which does not contain a substring

I know how to extract from a list items containing a substring but I prove unable to extract items which doesn't contain a substring.
May you give me the correct filter to use ?

Applescript:

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set theSource to ((path to desktop as text) & "Titres m4p 20190704.txt") as «class furl»
set theList to paragraphs of (read theSource)

--set newList to my itemsContaining:"Complete Jazz Series" inList:theList
set newList to my itemsWithout:"Complete Jazz Series" inList:theList
set theResult to my concatList:newList usingString:linefeed

#=====

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

#=====

on itemsWithout:theVal inList:theList
   set theArray to current application's NSArray's arrayWithArray:theList
   set thePred to current application's NSPredicate's predicateWithFormat:"self !=,CONTAINS %@" argumentArray:{theVal} # WRONG SYNTAX
   return (theArray's filteredArrayUsingPredicate:thePred) as list
end itemsWithout:inList:

#=====

on concatList:theList usingString:d1
   set anArray to current application's NSArray's arrayWithArray:theList
   return (anArray's componentsJoinedByString:d1) as text
end concatList:usingString:

#=====

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 5 juillet 2019  16:54:13

Offline

 

#2 2019-07-05 09:12:00 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3635

Re: filter items which does not contain a substring

I found a way to get the wanted result but I am always interested to know the correct filter.

Applescript:

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

set theSource to ((path to desktop as text) & "Titres m4p 20190704.txt") as «class furl»
set oldList to paragraphs of (read theSource)

set newList to my itemsContaining:"Complete Jazz Series" inList:oldList
set listWithout to my removeItemsInListInOrder:newList fromList:oldList

return {my concatList:newList usingString:linefeed, my concatList:listWithout usingString:linefeed}

#=====

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

#=====

on removeItemsInListInOrder:oldList fromList:newList
   set set2 to current application's NSSet's setWithArray:oldList
   set set1 to current application's NSMutableOrderedSet's orderedSetWithArray:newList
   set1's minusSet:set2
   return (set1's array()) as list
end removeItemsInListInOrder:fromList:

#=====

on concatList:theList usingString:d1
   set anArray to current application's NSArray's arrayWithArray:theList
   return (anArray's componentsJoinedByString:d1) as text
end concatList:usingString:

#=====

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 5 juillet 2019  17:11:35

Offline

 

#3 2019-07-05 09:14:31 am

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

Re: filter items which does not contain a substring

Hi Yvan.

The predicate string should be either "NOT self CONTAINS %@" or "! self CONTAINS %@". You can parenthesise the "self CONTAINS %@" part if you like: "NOT (self CONTAINS %@)" or "! (self CONTAINS %@").


NG

Offline

 

#4 2019-07-05 10:25:08 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3635

Re: filter items which does not contain a substring

Thanks Nigel, it's exactly what I wanted.
It's really fast.

Applescript:

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

my Germaine()

on Germaine()
   set p2d to path to desktop as text
   set theSource to (p2d & "Titres m4p 20190704.txt") as «class furl»
   set theList to paragraphs of (read theSource as «class utf8»)
   set startDate to current application's NSDate's |date|()
   set nbRows to count theList
   set newList to my itemsContaining:"Complete Jazz Series" inList:theList
   set listWithout to my itemsWithout:"Complete Jazz Series" inList:theList
   
   set theData to (nbRows as text) & linefeed & "items With" & linefeed & (my concatList:newList usingString:linefeed) & linefeed & "items Without" & linefeed & (my concatList:listWithout usingString:linefeed)
   set targetFile to p2d & "with or without.txt"
   my writeto(targetFile, theData, «class utf8», false)
   
   set timeDiff to startDate's timeIntervalSinceNow()
   display dialog "That took " & (-timeDiff as real) & " seconds."
   
   --> with 21548 lines in the source file "That took 0,479604959488 seconds."
end Germaine

#=====

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

#=====

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

#=====

on concatList:theList usingString:d1
   set anArray to current application's NSArray's arrayWithArray:theList
   return (anArray's componentsJoinedByString:d1) as text
end concatList:usingString:

#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)

on writeto(targetFile, theData, dataType, apendData)
   -- targetFile is the path to the file you want to write
   -- theData is the data you want in the file.
   -- dataType is the data type of theData and it can be text, list, record etc.
   -- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
   try
       set targetFile to targetFile as «class furl»
       set openFile to open for access targetFile with write permission
       if not apendData then set eof of openFile to 0
       write theData to openFile starting at eof as dataType
       close access openFile
       return true
   on error
       try
           close access targetFile
       end try
       return false
   end try
end writeto

#=====

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 5 juillet 2019  18:25:03

Last edited by Yvan Koenig (2019-07-05 10:26:27 am)

Offline

 

#5 2019-07-05 05:41:05 pm

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

Re: filter items which does not contain a substring

And for the sake of completeness, to make it ignore case you would use "CONTAINS[c]".


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

Offline

 

#6 2019-07-06 01:53:52 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3635

Re: filter items which does not contain a substring

Thanks for this info Shane.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 6 juillet 2019  09:53:46

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)