Comparing 2 nested lists

Hi everyone,

I’ve got 2 nested lists (list1, list2) that I want to compare - the comparison I want is making sure item’s 1 & 2 of list2 are within list1. If they aren’t, then I want to return the values of item 1 & 2 of list2.

Here is an example of my lists:

set list1 to {{"123", "abc"}}
set list2 to {{"123", "abc", "xyz"}, {"123", "def", "xyz"}}

Thanks a bunch for the help!

Uhh…okay that’s not exactly what I want to check :slight_smile: Technically what I want to compare is {item 1, item 2} of item 1 of list2 (iterating the list items) are anywhere within {item 1, item 2} of list1’s items. If they aren’t, I want to return those values. Hope that makes sense. Yikes, explaining nested lists, ughh.

perhaps something like

set list1 to {{"123", "abc"}}
set list2 to {{"123", "abc", "xyz"}, {"123", "def", "xyz"}, {"123", "abc", "uvw"}}
set retVal to ""

repeat with i from 1 to count of list2
	set testlist to items 1 thru 2 of (item i of list2)
	if list1 contains {testlist} then
		set retVal to retVal & "Item " & i & " of list2 contains list1." & linefeed
	end if
end repeat

return retVal

Is this what you are looking for?

set list1 to {{"123", "abc"}}
set list2 to {{"123", "abc", "xyz"}, {"123", "def", "xyz"}}
set x to checkList(list1, list2)


on checkList(list1, list2)
	set returnList to {}
	repeat with anItem in list2
		repeat with nestedItem in anItem
			repeat with checkItem in list1
				if nestedItem is not in checkItem then copy nestedItem to end of returnList
			end repeat
		end repeat
	end repeat
	return returnList
end checkList

Great! Except I should have also said that I need your “retVal” to be a list of the differences instead of just text. Thanks again for your help!!

Okay, Mike - I adjusted the code to return a list:

set list1 to {{"123", "abc"}}
set list2 to {{"123", "abc", "xyz"}, {"123", "def", "xyz"}, {"123", "abc", "uvw"}}

set retVal to {}

repeat with i from 1 to count of list2
	set testlist to items 1 thru 2 of (item i of list2)
	if list1 does not contain {testlist} then
		set retVal's end to testlist
	end if
end repeat

return retVal

Is there a way to return the original third item of list2, so that instead of returning {“123”, “def”} it returns {“123”, “def”, “xyz”}? Sorry for nitpicky-ness but that would be exactly what I needed.

Hmm…Even though “123” is in List1, you want it counted as OUT because {“123”, “abc”} is not a sub-list of item 2 of List2.

It think I understand. But…What would you want returned from
list2 = {{“123”, “abc”, “xyz”}, {“123”, “def”, “xyz”}, {“123”, “abc”, “uvw”} ,{“abc”, “123”, “STR”}, {“123”, “xtra”, “abc” }
"

Hi.

set list1 to {{"123", "abc"}}
set list2 to {{"123", "abc", "xyz"}, {"123", "def", "xyz"}, {"123", "abc", "uvw"}}

set retVal to {}

repeat with i from 1 to count of list2
	set testlist to (item i of list2)
	if (testlist does not start with item 1 of list1) then
		set end of retVal to testlist
	end if
end repeat

return retVal

Yeah, I technically am comparing ({item 1, item 2} of item x) of list2 to list1’s items, but what I want to return is something that says: {“123”, “abc”} of list2 are in list1, but {“123”, “def”} of list2 is NOT in list1, so return: {“123”, “def”, “xyz”} of list2.

Thanks for the reply, Nigel - although this returns all 3 items of list2, the real diff comparison I’m trying to get to is the diffs of {item 2} of item x from both list1 and list2 (item “x” so as to iterate through all of list2)

set list1 to {{“123”, “abc”}}
set list2 to {{“123”, “abc”, “xyz”}, {“123”, “def”, “xyz”}, {“123”, “abc”, “uvw”}}

set retVal to {}
repeat with i from 1 to count of list2
	set testlist to (item i of list2)
	if (testlist does not start with item 1 of list1) then
		copy testlist to end of retVal
	else
		copy (items 3 thru -1 of testlist) to end of retVal
	end if
end repeat

set finalList to {}
repeat with testlist in retVal
	repeat with i from 1 to count of testlist
		if not (finalList contains {item i of testlist}) then
			copy item i of testlist to end of finalList
		end if
	end repeat
	
end repeat
return finalList --{"xyz", "123", "def", "uvw"}

Thanks for all the help with this guys - as I read mikerickson’s post, it gave me another tip to try. Here’s what I ended up with that did what I was hoping for. The “& item -1 of (item i of list2)” line is what I added to give me all list2’s items:


set list1 to {{"123", "abc"}}
set list2 to {{"123", "abc", "xyz"}, {"123", "def", "xyz"}, {"123", "abc", "uvw"}}

set retVal to {}

repeat with i from 1 to count of list2
	set testlist to items 1 thru 2 of (item i of list2)
	if list1 does not contain {testlist} then
		set retVal's end to testlist & item -1 of (item i of list2)
	end if
end repeat

return retVal
--> {{"123", "def", "xyz"}}

There’s something wrong with your machine if it does. It actually produces exactly the same result as the script on which you finally settled. :slight_smile: