Here’s a method I use, two different examples that use the same “arrayOfDupesOnlyValues”
Basically need to get an arrayOfValues for the keys.
Create a countedSet from this arrayOfValues.
Filter / Create a arrayOfDupesOnlyValues where the the countedSet countForObject > 1
then I’ve shown two functions using this data to filter the original list.
- using some SMS Forder techniques to get an indexSet
- building a compoundPredicate to filter the original list
sorry didn’t have much time to build a test list
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
use script "BridgePlus" version "1.3.2"
load framework
-- classes, constants, and enums used
property NSCompoundPredicate : a reference to current application's NSCompoundPredicate
property NSCountedSet : a reference to current application's NSCountedSet
property NSDictionary : a reference to current application's NSDictionary
property NSPredicate : a reference to current application's NSPredicate
property SMSForder : a reference to current application's SMSForder
property NSArray : a reference to current application's NSArray
property NSString : a reference to current application's NSString
property NSMutableArray : a reference to current application's NSMutableArray
set listREC1 to {{title:"Track01", artist:"Artist02", album:"Greatest Hits"}, {title:"Track02", artist:"Artist02", album:"Greatest Hits"}, {title:"Track03", artist:"Artist03", album:"Best Ever"}, {title:"Track04", artist:"Artist04"}, {title:"Track05", artist:"Artist05", album:"Greatest Hits"}, {title:"Track06", artist:"Artist07", album:"Greatest Hits"}, {title:"Track08", artist:"Artist03", album:"Best Ever"}, {title:"Track99", artist:"Artist99"}}
set keys to {"artist", "album"}
property aTest1 : {}
property aTest2 : {}
set aTest1 to (my groupItemsInList:listREC1 usingGroupKeys:keys) as list
--> {{{title:"Track03", album:"Best Ever", artist:"Artist03"}, {title:"Track08", album:"Best Ever", artist:"Artist03"}}, {{title:"Track01", album:"Greatest Hits", artist:"Artist02"}, {title:"Track02", album:"Greatest Hits", artist:"Artist02"}}}
set aTest2 to (my groupItemsWithPredicateInList:listREC1 usingGroupKeys:keys) as list
--> {{{title:"Track03", album:"Best Ever", artist:"Artist03"}, {title:"Track08", album:"Best Ever", artist:"Artist03"}}, {{title:"Track01", album:"Greatest Hits", artist:"Artist02"}, {title:"Track02", album:"Greatest Hits", artist:"Artist02"}}}
-- FIND GROUP ITEMS USING SMS FORDERs indexsOfItems
on groupItemsInList:originalList usingGroupKeys:dupeGroupKEYS
set groupedArray to NSMutableArray's array()
set sourceArray to NSArray's arrayWithArray:originalList
set valuesOfArray to SMSForder's subarraysFrom:sourceArray usingKeys:dupeGroupKEYS outKeys:(missing value) |error|:(missing value)
set dupeValues to (my onlyDupeCountedItemsFromArray:valuesOfArray)
repeat with i from 1 to count of dupeValues
set currentValues to (dupeValues's objectAtIndex:(i - 1)) as list
set matchedIndexs to (SMSForder's indexesOfItems:{currentValues} inArray:valuesOfArray inverting:false) as list
set matchedIndexSet to (SMSForder's indexSetWithArray:matchedIndexs)
set matchedObjects to (sourceArray's objectsAtIndexes:matchedIndexSet)
(groupedArray's insertObject:matchedObjects atIndex:(groupedArray's |count|()))
end repeat
return groupedArray
end groupItemsInList:usingGroupKeys:
-- FIND GROUP ITEMS USING FILTER PREDICATE
on groupItemsWithPredicateInList:originalList usingGroupKeys:dupeGroupKEYS
set groupedArray to NSMutableArray's array()
set sourceArray to NSArray's arrayWithArray:originalList
set dupeValues to (my onlyDupeCountedValuesFromArray:sourceArray forKeys:dupeGroupKEYS)
repeat with i from 1 to count of dupeValues
set currentValues to (dupeValues's objectAtIndex:(i - 1))
set aPred to (my createCompoundPredicateForKeys:dupeGroupKEYS matchingValues:currentValues)
set matchedItems to (sourceArray's filteredArrayUsingPredicate:aPred)
set aCount to matchedItems's |count|()
if (aCount > 1) then
(groupedArray's insertObject:matchedItems atIndex:(groupedArray's |count|()))
end if
end repeat
return groupedArray
end groupItemsWithPredicateInList:usingGroupKeys:
-- UTILITIES
on createCompoundPredicateForKeys:groupKeys matchingValues:matchValues
set allPreds to NSMutableArray's array()
set keysArray to NSArray's arrayWithArray:groupKeys
repeat with i from 1 to count of groupKeys
set currentKey to (keysArray's objectAtIndex:(i - 1))
set matchValue to (matchValues's objectAtIndex:(i - 1))
set aPred to NSPredicate's predicateWithFormat_("%K == %@", currentKey, matchValue)
(allPreds's addObject:aPred)
end repeat
set aCompoundPred to (NSCompoundPredicate's andPredicateWithSubpredicates:allPreds)
return aCompoundPred
end createCompoundPredicateForKeys:matchingValues:
on onlyDupeCountedValuesFromArray:aArray forKeys:groupKeys
set sourceArray to NSArray's arrayWithArray:aArray
set valuesOfArray to SMSForder's subarraysFrom:sourceArray usingKeys:groupKeys outKeys:(missing value) |error|:(missing value)
set dupeValues to (my onlyDupeCountedItemsFromArray:valuesOfArray)
return dupeValues
end onlyDupeCountedValuesFromArray:forKeys:
on onlyDupeCountedItemsFromArray:aArray
set dupeItems to NSMutableArray's array()
set aCountedSet to NSCountedSet's setWithArray:aArray
set uniqueItems to aCountedSet's allObjects()
repeat with i from 1 to count of uniqueItems
set aItem to (uniqueItems's objectAtIndex:(i - 1))
set aCount to (aCountedSet's countForObject:aItem)
if (aCount > 1) then
(dupeItems's addObject:aItem)
end if
end repeat
return dupeItems
end onlyDupeCountedItemsFromArray: