Search/find in a list

Hi,

Here is a sample of my code:


set ProductList to {¬
	{"Product1,1", "Product Name 1"}, ¬
	{"Product1,2", "Product Name 2"}, ¬
	{"Product2,1", "Product Name 3"}, ¬
	{"Product3,1", "Product Name 4 (Extra)"}}

Simple question but cannot find the answer. I know I can ask AppleScript to return an item number but this is not what I 'm looking for. I want to ask, please return the name of “Product2,1” and the answer should be “Product Name 3”. I tried many syntax but always get an error numbers or not allowed.

I hope someone can give me the right answer.

Thank you very much in advance ! :slight_smile:

Hello

As far as I remember, it’s a good job for Shane STANLEY’s ASObjC Runner.app (free).

If I understand well, the function :

look in list‚v : Get the indexes of an object or list of objects in a list, or if the sublists parameter is true, in the sublists of a list.
look in list list of any : A list of items, or a list of sublists of items.
[matching any] : An item to look for.
[matching items list of any] : A list of items to look for.
[sublists boolean] : If true, operates on the list’s sublists rather than the list itself. Default is false.
[inverting boolean] : If true, returns indexes of items that don’t match. Default is false.
[only first boolean] : If true, only the index of the first match will be returned. Default is false.
→ any : The list of indexes, or a list of them.

would give you the index of the sublist containing the searched key so you will easily get the wanted info.

Yvan KOENIG (VALLAURIS, France) vendredi 3 août 2012 23:50:59

You’re looking for an hash table, AS doesn’t have one but the closest you can get is using records. Keys are in hash tables strings but in AS they’re identifiers and therefore sometimes a bit clumsy.

So you’re list would look like:

set ProductList to {Product1_1:"Product Name 1", Product1_2:"Product Name 2", Product2_1:"Product Name 3", Product3_1:"Product Name 4 (Extra)"}

return Product1_1 of ProductList

Then to have multiple properties to 1 product you could use

set ProductList to {Product1_1:{id:1, name:"Product Name 1"}, Product1_2:{id:2, name:"Product Name 2"}, Product2_1:{id:3, name:"Product Name 3"}, Product3_1:{id:4, name:"Product Name 4 (Extra)"}}

return name of Product1_1 of ProductList

Because keys are identifiers, you will get an error if the identifier/item doesn’t exists. To avoid these errors you can use the following code to call any product.

return name of product11 of (ProductList & {product11:{id:0, name:missing value}})

Now we add a value at the end of the record, if not exists, to return when the object doesn’t exist in productList.

I agree, but I’d probably take a different tack, like this:

set ProductList to {¬
	{"Product1,1", "Product Name 1"}, ¬
	{"Product1,2", "Product Name 2"}, ¬
	{"Product2,1", "Product Name 3"}, ¬
	{"Product3,1", "Product Name 4 (Extra)"}}
tell application id "au.com.myriad-com.ASObjC-Runner" -- ASObjC Runner.app
	set newLists to modify list ProductList with cols to rows
	--> {{"Product1,1", "Product1,2", "Product2,1", "Product3,1"}, {"Product Name 1", "Product Name 2", "Product Name 3", "Product Name 4 (Extra)"}}
	set theRecords to link values (item 2 of newLists) with labels (item 1 of newLists)
	--> {|product1,2|:"Product Name 2", |product3,1|:"Product Name 4 (Extra)", |product2,1|:"Product Name 3", |product1,1|:"Product Name 1"}
	set theResult to value for label "Product1,2" in records theRecords
	-->{"Product Name 2"}
end tell

Hello.

This is just another way, having reworked Matt Neuburgs filter handler slightly to work on lists of lists.

I just present this way here, as an alternative, having no single bad word to say about AsobjC Runner.app it is just an alternative way, using pure applescript.

Edit

I have reworked the handler a little, so that you can choose wich item in the sublists you search.


on run
	global searchterm
	set ProductList to {¬
		{"Product1,1", "Product Name 1"}, ¬
		{"Product1,2", "Product Name 2"}, ¬
		{"Product2,1", "Product Name 3"}, ¬
		{"Product3,1", "Product Name 4 (Extra)"}}
	
	set searchterm to "Product2,1"
	
	set res to item 2 of item 1 of _filterL(ProductList, amatch, 1)
	-- > (*Product Name 3*)
end run
-- © Matt Neuburg AppleScript The Definitive Guide Second Edition.
-- reworked to work on lists of lists, finding criteria in chosen item of the sublist
on _filterL(l, crit, itemNo)
	script filterer
		property criterion : crit
		property itemnum : itemNo
		on _filter(l)
			if l = {} then return l
			if criterion(item itemnum of item 1 of l) then
				return {item 1 of l} & (_filter(rest of l))
			else
				return _filter(rest of l)
			end if
		end _filter
	end script
	return filterer's _filter(l)
end _filterL

on amatch(x)
	global searchterm
	if searchterm is in contents of x then return true
	return false
end amatch


Thank you to all suggestions and examples, I really appreciate and more specially pure AppleScript code. :slight_smile: I should be able to do something with those. :wink: