trouble with repeat with i from 1 to count of

Hi
having trouble with this script repeat

tell application "Microsoft Excel"
	launch
	--other script got these lists
	set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}
	
	set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
		set countchecklist to {}
	repeat with i from 1 to count of lists of checkList
		--return count of lists of checkList(returns 10 true)
				repeat with i from 1 to count of lists of testList3combos15
						set counttest to 0
			if list i of lists of testList3combos15 contains (item 1 of list i of checkList) then set counttest to counttest + 1
			if list i of lists of testList3combos15 contains (item 2 of list i of checkList) then set counttest to counttest + 1
			if list i of lists of testList3combos15 contains (item 3 of list i of checkList) then set counttest to counttest + 1
			if list i of lists of testList3combos15 contains (item 4 of list i of checkList) then set counttest to counttest + 1
			if list i of lists of testList3combos15 contains (item 5 of list i of checkList) then set counttest to counttest + 1
			if list i of lists of testList3combos15 contains (item 6 of list i of checkList) then set counttest to counttest + 1
			set end of countchecklist to counttest
			--return countchecklist--returns {1} true for list 1 of checkList
		end repeat
				return countchecklist --does,t get this far
	end repeat
	return countchecklist
end tell


event log returns

“Can’t get list 11 of {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}.”

There is no list 11 --return count of lists of checkList(returns 10 true),
So where is list 11 coming from?
if I run repeat with i from 1 to count of lists of checkList-1, I get Can’t get list 0 of
Any help to understand this would be appreciated.
Thanks
bills

Hi,

list is a reserved word and does not represent the elements of a list.
In AppleScript the elements of a list are items, for example


item 2 of item 3 of checkList --> 11


tell application "Microsoft Excel"
	launch
	--other script got these lists
	set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}
	
	set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
	set countchecklist to {}
	repeat with i from 1 to count checkList
		--return count of lists of checkList(returns 10 true)
		repeat with i from 1 to count testList3combos15
			set counttest to 0
			if item i of testList3combos15 contains (item 1 of item i of checkList) then set counttest to counttest + 1
			if item i of testList3combos15 contains (item 2 of item i of checkList) then set counttest to counttest + 1
			if item i of testList3combos15 contains (item 3 of item i of checkList) then set counttest to counttest + 1
			if item i of testList3combos15 contains (item 4 of item i of checkList) then set counttest to counttest + 1
			if item i of testList3combos15 contains (item 5 of item i of checkList) then set counttest to counttest + 1
			if item i of testList3combos15 contains (item 6 of item i of checkList) then set counttest to counttest + 1
			set end of countchecklist to counttest
			--return countchecklist--returns {1} true for list 1 of checkList
		end repeat
		return countchecklist --does,t get this far
	end repeat
	return countchecklist
end tell


Hi Stefan.

Actually, list does represent elements of lists which are lists, although it may be slightly more efficient to refer to them as items where you don’t need to differentiate between lists and other elements. (I haven’t checked this recently.)

The problem with bills’s script is that the nested repeats are using the same loop variable ‘i’, the inner one taking priority; so when then inner repeat gets up to 11, the variable can no longer index items in the 10-list ‘checkList’. Changing one of the variables to something else, say ‘j’, cures the problem.

The ‘lists of’ part of the list references could be dropped though, since it implies a new lists of lists each time. And none of the posted code has anything to do with Microsoft Excel.

--tell application "Microsoft Excel"
--launch
--other script got these lists
set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set countchecklist to {}
repeat with i from 1 to (count checkList)
	--return count of lists of checkList(returns 10 true)
	repeat with j from 1 to (count testList3combos15)
		set counttest to 0
		if list j of testList3combos15 contains (item 1 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 2 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 3 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 4 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 5 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 6 of list i of checkList) then set counttest to counttest + 1
		set end of countchecklist to counttest
		--return countchecklist--returns {1} true for list 1 of checkList
	end repeat
	-- return countchecklist --does,t get this far
end repeat
return countchecklist
--end tell

thanks Nigel, again I’ve learned/learnt something new :slight_smile:

Hello.

I didn’t know that either, but it sounds logical. :slight_smile:

I belieive contains, is as costly as is in, and since the testListCombo3 lists contains only 3 items, and the checklist 5 items, I inverted the tests, to make it run just a tad faster if possible.

--launch
--other script got these lists
-- I surmise that all lists of checklist contains 3  unique numbers, and that testList3combos15 does the same.

set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set countchecklist to {}
repeat with i from 1 to (count checkList)
	--return count of lists of checkList(returns 10 true)
	repeat with j from 1 to (count testList3combos15)
		set counttest to 0
		if item 1 of list j of testList3combos15 is in (list i of checkList) then set counttest to counttest + 1
		if item 2 of list j of testList3combos15 is in (list i of checkList) then set counttest to counttest + 1
		if item 3 of list j of testList3combos15 is in (list i of checkList) then set counttest to counttest + 1
		set end of countchecklist to counttest
		--return countchecklist--returns {1} true for list 1 of checkList
	end repeat
	# return countchecklist --does,t get this far
end repeat
return countchecklist


[b]Edit[/b] This will only work if both the testLists and checkLists contains unique numbers.

Good thinking, McUsrII. :cool:

The ultimate, of course, would be to assign the checkList list and the testList3combos15 list’s items to variables so that they don’t need to be fetched from the master lists for each test:

--launch
--other script got these lists
-- I surmise that all lists of checklist contains 3  unique numbers, and that testList3combos15 does the same.

set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set countchecklist to {}
repeat with i from 1 to (count checkList)
	set thisCheck to list i of checkList
	--return count of lists of checkList(returns 10 true)
	repeat with j from 1 to (count testList3combos15)
		set {a, b, c} to list j of testlist3combos15
		set counttest to 0
		if a is in thisCheck then set counttest to counttest + 1
		if b is in thisCheck then set counttest to counttest + 1
		if c is in thisCheck then set counttest to counttest + 1
		set end of countchecklist to counttest
		--return countchecklist--returns {1} true for list 1 of checkList
	end repeat
	-- return countchecklist --does,t get this far
end repeat
return countchecklist

That helps even more! :slight_smile:

And given the proviso with your inversion, the asssignment-to-variable idea could be used if it was necessary to do things the original way round after all:

--tell application "Microsoft Excel"
--launch
--other script got these lists
set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set countchecklist to {}
repeat with i from 1 to (count checkList)
	set {a, b, c, d, e, f} to list i of checkList
	--return count of lists of checkList(returns 10 true)
	repeat with j from 1 to (count testList3combos15)
		set thisCombo to list j of testList3combos15
		set counttest to 0
		if thisCombo contains a then set counttest to counttest + 1
		if thisCombo contains b then set counttest to counttest + 1
		if thisCombo contains c then set counttest to counttest + 1
		if thisCombo contains d then set counttest to counttest + 1
		if thisCombo contains e then set counttest to counttest + 1
		if thisCombo contains f then set counttest to counttest + 1
		set end of countchecklist to counttest
		--return countchecklist--returns {1} true for list 1 of checkList
	end repeat
	-- return countchecklist --does,t get this far
end repeat
return countchecklist
--end tell

Yes, I think that makes a significant difference.

That looks a fair assumption.

Here’s another method, this time actually quite a bit slower. But it might scale a bit better with longer sublists.

use framework "Foundation"

set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set countchecklist to {}
repeat with list1 in checkList
	repeat with list2 in testList3combos15
		set newList to list1 & list2
		set end of countchecklist to (length of newList) - ((current application's NSSet's setWithArray:newList)'s |count|())
	end repeat
	return countchecklist --does,t get this far
end repeat
return countchecklist

Hello NIgel.

Yes, that works a lot better if the values aren’t unique. :slight_smile:

I was also thinking of making one, where the number of items in the tesLists, may vary, (since the number of items in it are named. That way, it isn’t necessary, to hardcode versions, for the number of items, Then the assertion about unique values in both lists must hold. This can of course also be inverted.


--launch
--other script got these lists
-- I surmise that all lists of checklist contains 3  unique numbers, and that testList3combos15 does the same.

set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set countchecklist to {}
set itemCount to count list 1 of testList3combos15

repeat with i from 1 to (count checkList)
	--return count of lists of checkList(returns 10 true)
	
	repeat with j from 1 to (count testList3combos15)
		set listToClassify to list j of testList3combos15
		set counttest to 0
		repeat with k from 1 to itemCount
			if item k of listToClassify is in (list i of checkList) then set counttest to counttest + 1
		end repeat
		set end of countchecklist to counttest
	end repeat
	# return countchecklist --does,t get this far
end repeat
return countchecklist

I’ve just noticed that the script and all our variations contain two ‘return countchecklist’ lines! The first, inside the repeat, is what’s been returning the results we’ve been seeing. It should be removed so that the line at the end returns the correct, much longer result.

Hello Nigel.

Good spot! :slight_smile:

I reran, your first example, without that return statement, towards my own, and I checked the results by text comparision in TextWrangler, it all worked out.

That was another way of doing it Shane. :slight_smile:

I’ve now commented out the offending line in my posts above in case bills doesn’t get this far in the technical discussion. I see McUsrII’s been doing the same thing. :slight_smile:

Yes.
And with a ‘#’ ! since ‘”’ entered directly into a post breaks the script, since it becomes translated into em-dash. :slight_smile:

We can of course optimize this a little bit further, should the OP need it, but it is smart to wait, until we know what he is after, because then it becomes at least a tad messier, with the script object.

I’ll just explain the math, for those who don’t understand who to compute the advantage of reducing the statements in a loop.

If you have one statement in a loop, that are iterated over 10 times, then the statement is executed 10 times, and this can be expressed as L1 X S. If you have 2 Loops, then the inner loop is exeuted the number of times you loop over it.
That can be expressed as L2 X L1 X S

So, in a case where the outer loop is executed 10 times, and the inner loop ten times and 5 statements are executed inside, then that is 10 X 10X 5 = 500, in this case, it is possible that we can get a way with 3 statements in the inner loop, reducing the total number of statements executed with 200. Therefore we look at possibilities for inverting some condition, to reduce the number of statements, if we can.

It is the same principle, as when one writes an SQL query, One should arrange the query, so that the largest number of items, are filtered away at the start, so the latter part of the query executes as fast as possible.

What’s happening on your computer? Two ordinary dashes (“–”) work perfectly well here.

In the current situation, the fewer inverted statements are checking longer lists. So in a worse-case scenario, each might take longer than one of the more numerous original statements it replaces. But overall, we may expect a speed gain. Still, as you’ve rightly born in mind, the inversion here is notionally checking the items in the ‘checkList’ lists rather than those in the ‘testList3combos15’ ones, so one must be careful to ensure that the two approaches do in fact correspond.

Hello.

I suspect the reason for the ‘”’ as em dash, to be that the internet is really standardized on iso-8859-1, and not UTF8.
So, I have an ‘outlandish’ keyboard. :slight_smile:

I agree, if the values in the CheckLists aren’t unique, then the approach is unusable.

And I also agree, to the fact that in the end, it is exactly the same number of comparisions that are performed inside the list, it is just that using contains or is in, reduces the number of statements, and that the containment operation, is faster than a single statement of itself. It also depends on if there are any match, or not in the list, and where in the list it is. I am still pretty sure that this is faster than having five statements, that checks three items, but if you had many lists with no matches, then I guess the other way around would be better-

Reading the comments about the speed efficiency in the approach to the filtering of lists prior to some loop reminded of something I remember reading some years ago: this stated that we could use Lists or Records. If I recall correctly ( I think it was the Kochan book on AS…) the suggestion was that it was much more efficient in terms of speed to access a large set of records compared to looping through lists.

I understand that perhaps it can be more complicated to think about the correct structure of records, and lists are easy to set up and deal with, but as the data set gets larger, the payoff increases.

This is an abstract statement coming from a diminishing memory and I offer no code as an example, but I would be interested to hear if anybody has a formed view on this.

Hi.

I don’t recall anything of that nature. By and large, I think that dealing with lists is faster than dealing with records ” in AppleScript, anyway. And of course if you’re starting with lists, as here, there’d be the additional time needed to transfer their data to records. I can’t really say any more than that as I can’t fully picture what you’re describing.

There is one phenomenon that’s often exploited. Access to items in long lists is usually very much faster if the references to the items include references to the list variables, in the context of the script in which they occur. eg:

-- someList is a variable to which is assigned a long list.

 -- Normal item reference.
item x of someList

-- Item reference where the list variable is referenced too:
item x of someList of someScript

But I don’t think that’s what you had in mind.

Edit: omitted word noticed and rectified.

Hi
Thanks for the help.
I had (set countchecklist to {}) in the wrong place to get the results I wanted.
Basically what I was doing was checking which of the 6 number list got the most 3 number matches of the 3 number lists.
Will have to remember not to use the same variable twice.
The numbers are unique.
Heres how it turned out. Both versions give the same result.

--tell application "Microsoft Excel"
--launch
--other script got these lists
set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}

set HighCountList to {}
repeat with i from 1 to (count checkList)
	set countchecklist to {}
	repeat with j from 1 to (count testList3combos15)
		set counttest to 0
		if list j of testList3combos15 contains (item 1 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 2 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 3 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 4 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 5 of list i of checkList) then set counttest to counttest + 1
		if list j of testList3combos15 contains (item 6 of list i of checkList) then set counttest to counttest + 1
		set end of countchecklist to counttest
	end repeat
	--gets 3 matches	
	set CountHighHits to 0
	repeat with k from 1 to the count of the countchecklist
		if item k of countchecklist is 3 then set CountHighHits to CountHighHits + 1
	end repeat
	set end of HighCountList to CountHighHits
end repeat
--get highest number of 3 hits
set the highHit to ""
repeat with i from 1 to the count of the HighCountList
	set thisItem to item i of the HighCountList
	if the highHit is "" then
		set the highHit to thisItem
	else if thisItem is greater than the highHit then
		set the highHit to item i of the HighCountList
	end if
end repeat
--finds 1st highest match in list
set the listCount to 0
repeat with i from 1 to the count of the HighCountList
	set thisItem to item i of the HighCountList
	if thisItem is less than highHit then set listCount to listCount + 1
	if thisItem is highHit then exit repeat
end repeat
set MostMatches to list (listCount + 1) of checkList

return MostMatches

--end tell
--launch
--other script got these lists
-- I surmise that all lists of checklist contains 3  unique numbers, and that testList3combos15 does the same.

set testList3combos15 to {{3, 9, 11}, {3, 12, 13}, {7, 8, 9}, {3, 6, 11}, {6, 7, 11}, {2, 3, 12}, {3, 6, 8}, {3, 5, 7}, {2, 11, 13}, {8, 9, 13}, {2, 9, 11}, {7, 10, 13}, {2, 6, 12}, {3, 6, 10}, {1, 2, 7}, {1, 3, 6}, {1, 9, 13}, {1, 2, 13}, {2, 4, 6}, {1, 6, 9}, {12, 13, 14}, {4, 7, 14}, {2, 12, 14}, {3, 4, 8}, {3, 10, 14}, {6, 8, 14}, {3, 12, 15}, {7, 8, 10}, {2, 4, 11}, {1, 13, 14}, {3, 4, 15}, {3, 4, 10}, {2, 12, 15}, {1, 7, 10}, {10, 13, 15}, {2, 4, 15}, {1, 4, 9}, {1, 13, 15}, {5, 9, 15}, {4, 8, 14}, {8, 11, 15}, {1, 12, 14}, {1, 8, 14}, {5, 8, 14}, {4, 10, 14}, {4, 10, 11}, {1, 14, 15}, {1, 8, 10}, {1, 10, 15}}

set checkList to {{6, 10, 4, 1, 11, 8}, {9, 3, 7, 4, 12, 13}, {14, 11, 4, 12, 10, 13}, {2, 7, 6, 9, 1, 5}, {7, 8, 2, 11, 15, 1}, {12, 3, 11, 1, 13, 15}, {15, 4, 10, 8, 5, 12}, {8, 13, 1, 12, 9, 3}, {7, 3, 6, 11, 8, 5}, {15, 2, 1, 13, 11, 9}}
set HighCountList to {}
repeat with i from 1 to (count checkList)
	set thisCheck to list i of checkList
	set countchecklist to {}
	
	repeat with j from 1 to (count testList3combos15)
		set {a, b, c} to list j of testList3combos15
		
		
		set counttest to 0
		if a is in thisCheck then set counttest to counttest + 1
		if b is in thisCheck then set counttest to counttest + 1
		if c is in thisCheck then set counttest to counttest + 1
		set end of countchecklist to counttest
	end repeat
	--gets 3 matches	
	set CountHighHits to 0
	repeat with k from 1 to the count of the countchecklist
		if item k of countchecklist is 3 then set CountHighHits to CountHighHits + 1
	end repeat
	set end of HighCountList to CountHighHits
	
end repeat

--gets the highest amount of 3 matches
set the highHit to ""
repeat with i from 1 to the count of the HighCountList
	set thisItem to item i of the HighCountList
	if the highHit is "" then
		set the highHit to thisItem
	else if thisItem is greater than the highHit then
		set the highHit to item i of the HighCountList
	end if
end repeat
--finds 1st highest match in list
set the listCount to 0
repeat with i from 1 to the count of the HighCountList
	set thisItem to item i of the HighCountList
	if thisItem is less than highHit then set listCount to listCount + 1
	if thisItem is highHit then exit repeat
end repeat

set MostMatches to list (listCount + 1) of checkList
return MostMatches

Thanks again
bills

Hi bills.

Thanks for getting back with your final script.

If you’re interested, besides the other optimisations we’ve mentioned above, this part at the end of the script(s) .

set the highHit to ""
repeat with i from 1 to the count of the HighCountList
	set thisItem to item i of the HighCountList
	if the highHit is "" then
		set the highHit to thisItem
	else if thisItem is greater than the highHit then
		set the highHit to item i of the HighCountList
	end if
end repeat
--finds 1st highest match in list
set the listCount to 0
repeat with i from 1 to the count of the HighCountList
	set thisItem to item i of the HighCountList
	if thisItem is less than highHit then set listCount to listCount + 1
	if thisItem is highHit then exit repeat
end repeat
set MostMatches to list (listCount + 1) of checkList

. can be condensed to .

set the highHit to ""
repeat with i from 1 to (count the HighCountList)
	set thisItem to item i of the HighCountList
	if the highHit is "" or thisItem is greater than the highHit then
		set the highHit to thisItem
		set highHitIndex to i
	end if
end repeat
set MostMatches to list highHitIndex of checkList