Add [only]new list to a list of list

I have a handler that checks and adds a list (contains string only) to a list of list if it does not already exist in the list of list. This time, I am not dealing with a large number of items. I am just wondering if there is a better way to code.

Thanks


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set theMainListOfList to {{"a", "b"}, {"c", "d"}}

set theNewList to {"a", "b"}
addNewItemToLOL(theNewList, theMainListOfList)
-- return {{"a", "b"}, {"c", "d"}}

set theNewList to {"a", "c"}
addNewItemToLOL(theNewList, theMainListOfList)
-- return {{"a", "b"}, {"c", "d"}, {"a", "c"}}

on addNewItemToLOL(theL, theLOL)
	set theTransformedLOL to {}
	repeat with each in theLOL
		set end of theTransformedLOL to each as text
	end repeat
	if theTransformedLOL contains (theL as text) then
	else
		set end of theLOL to theL
	end if
end addNewItemToLOL

([quote] tags changed to [applescript] by NG.)

I don’t know if it’s better but it works:

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

-- Handler borrowed from Shane Stanley's Everyday AppleScriptObjC
on makeUniqueListOf:theList
	set theSet to current application's NSOrderedSet's orderedSetWithArray:theList
	return (theSet's array()) as list
end makeUniqueListOf:


set theMainListOfList to {{"a", "b"}, {"c", "d"}}

set end of theMainListOfList to {"a", "b"}
set end of theMainListOfList to {"k", "g"}

its makeUniqueListOf:theMainListOfList --> {{"a", "b"}, {"c", "d"}, {"k", "g"}}

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 8 juillet 2020 19:57:22

Hi ngan.


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set theMainListOfList to {{"a", "b"}, {"c", "d"}}

set theNewList to {"a", "b"}
addNewItemToLOL(theNewList, theMainListOfList)
-- return {{"a", "b"}, {"c", "d"}}

set theNewList to {"a", "c"}
addNewItemToLOL(theNewList, theMainListOfList)
-- return {{"a", "b"}, {"c", "d"}, {"a", "c"}}

on addNewItemToLOL(theL, theLOL)
	if (theLOL does not contain {theL}) then -- or: if ({theL} is not in theLOL) then
		set end of theLOL to theL
	end if
end addNewItemToLOL

return theMainListOfList
--> {{"a", "b"}, {"c", "d"}, {"a", "c"}}

The reason for checking if theLOL contains {theL} rather than simply if it contains theL is because “contains” means “contains as a section” rather than “contains as an item”. So {{“a”, “c”}} is a section of {{“a”, “b”}, {“c”, “d”}, {“a”, “c”}}, whereas {“a”, “c”} is a section of {{“a”, “b”}, {“c”, “d”}, “a”, “c”}.

Hope this makes sense. When you write something like if myList contains “a”, “a” is automatically coerced to the list {“a”} for the operation, which is why leaving off the braces works in that case. But since {“a”, “c”} is already a list, it has to be explicitly written in a list to indicate that it’s the list and not the two consecutive items whose presence you want to check.

Thanks! No wonder…

I initially also use if theLOL contains theL but it doesn’t work coz I ignore the fact that theL is, in fact, a list {theL}.

I just found another snippet from my inventory through searching from the internet. I should credit the source but in early days I didn’t have the sense to keep the source of the code.

One difference is that the ASObjC approach will always be case-sensitive, whereas the other will be case-insensitive by default (but changeable).

Thanks for the reminder.