Problem conveting a list of strings to a list of records

As a relative newbie to AppleScript, I’ve been concocting little projects in order to learn about various data structures, etc. Predictably, I’ve hit a snag that I can’t figure out.

The exercise is to take a list of 2-character strings and convert it to a list of 2-property records. The property labels are predefined. For example, the list {“AS”, “KS”} would become {{Value:“A”, Suit:“S”}, {Value:“K”, Suit:“S”}}. There are 52 items in my original list (such as a deck of cards).

I set up a loop to build my converted list and it seems to build just fine within the loop. But when I exit the loop and look at the finished product, it contains only the final item of the original data repeated 52 times. On closer examination I notice that the entire new array changes to the latest data on each pass of the loop.

This might have something to do with copy vs. set. I’ve played around with that but with no success. I’m stumped. Here’s the code. I’ve included a debug variable so that I can look at my converted deck for every iteration of the loop. Any suggestions or insights will be much appreciated.

set debugOn to false

set the Deck to {"AS", "KS", "QS", "JS", "TS", "9S", "8S", "7S", "6S", "5S", "4S", "3S", "2S", "AH", "KH", "QH", "JH", "TH", "9H", "8H", "7H", "6H", "5H", "4H", "3H", "2H", "AD", "KD", "QD", "JD", "TD", "9D", "8D", "7D", "6D", "5D", "4D", "3D", "2D", "AC", "KC", "QC", "JC", "TC", "9C", "8C", "7C", "6C", "5C", "4C", "3C", "2C"}
set card to {Value:"", Suit:""}
set newDeck to {}

repeat with eachItem from 1 to count of Deck
	set Value of card to first character of item eachItem of Deck
	set Suit of card to second character of item eachItem of Deck
	set newDeck to newDeck & {card}
	if debugOn then display dialog ¬
		"There are " & (count newDeck) & " cards in the deck." & return & ¬
		"This pass is " & eachItem & "." & return & ¬
		"Value of last card added is " & Value of item -1 of newDeck & "." & return & ¬
		"Suit of last card added is " & Suit of item -1 of newDeck & "."
end repeat

get newDeck

How about…

property deckSuits : {"S", "H", "D", "C"}
property deckCards : {"A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2"}

set deck to getNewDeck()

to getNewDeck()
	set tmpDeck to {}
	repeat with tmpSuit in deckSuits
		repeat with tmpCard in deckCards
			copy {cSuit:(tmpSuit as string), cValue:(tmpCard as string)} to the end of tmpDeck
		end repeat
	end repeat
	return tmpDeck
end getNewDeck


Hi John,

Yes you’re right. when you ‘set’ each list item to the same list, they share values. You can do two things. Instead of:

set newDeck to newDeck & {card}


copy card to end of newDeck

This is the fastest way. You can also use the ‘contents’.

set newDeck to newDeck & {contents of card}

This concatenates the value of of ‘card’ instead of a reference to ‘card’.


Thanks to both Kel and Jobu.

I looks like the critical issue is “copy” vs. “set”. I’ll play around with the “contents” filter as well. There are so many ways to deal with a problem; so much to learn. I like Jobu’s nested loop–very succinct.

I’m impressed with how rapidly the responses came after I posted the question. What a great group and resource!

Thanks again.

And, if you’re playing with cards, run this script by Kai:

set d to {}
repeat with s in «data utxt2661266326622660» as Unicode text
	repeat with c in {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}
		set d's end to c & s
	end repeat
end repeat

Very cool! I tip my hat to Kai!