在Pharo中如何迭代Set并选取元素?如何遍历Set内字典筛选指定键?
Hey there! Let's tackle your Pharo questions step by step—working with Sets and Dictionaries is super common in Smalltalk environments like Pharo, so let's break this down clearly.
First off, even though Sets are unordered collections (you can't rely on a fixed iteration order), Pharo gives you all the standard collection tools to work with them. Here are the most practical methods:
Basic iteration with
do:: Use this when you just need to run code for every element in the Set. Example:| mySet | mySet := #(cat dog bird fish) asSet. mySet do: [ :eachAnimal | Transcript show: 'Checking animal: ', eachAnimal; cr ]Filter elements with
select:: This returns a new Set containing only elements that match your condition. Say you want animals with names shorter than 4 characters:shortNamedAnimals := mySet select: [ :each | each size < 4 ]Transform elements with
collect:: Create a new collection by applying a function to each element. For example, convert all animal names to lowercase:lowercaseAnimals := mySet collect: [ :each | each asLowercase ]
Your specific use case is a Set holding Dictionaries, so let's use your exact example to show how to extract or filter based on keys. First, let's define the Set properly in Pharo code (so you can test this yourself):
| dictSet | dictSet := Set new add: (Dictionary new at: 'age' put: '25'; at: 'code' put: 2512; yourself); add: (Dictionary new at: 'age' put: '40'; at: 'code' put: '1243'; yourself); add: (Dictionary new at: 'age' put: '35'; at: 'code' put: '7854'; yourself); yourself.
Now, here are common operations you might need:
Extract values for a specific key from all Dictionaries: If you want to collect all the 'age' values, use
collect::allAges := dictSet collect: [ :eachDict | eachDict at: 'age' ]This gives you a Set containing
'25','40','35'(order isn't guaranteed, since it's a Set).Filter Dictionaries by a key-based condition: Suppose you want only Dictionaries where 'age' is greater than 30. You'll need to convert the string 'age' value to a number first:
olderPeople := dictSet select: [ :eachDict | (eachDict at: 'age') asNumber > 30 ]This returns a new Set with the two Dictionaries where age is 40 and 35.
Extract multiple keys from each Dictionary: If you want to create a new collection of Dictionaries with only specific keys (like 'age' and 'code'), do this:
trimmedDicts := dictSet collect: [ :eachDict | Dictionary new at: 'age' put: (eachDict at: 'age'); at: 'code' put: (eachDict at: 'code'); yourself ]Alternatively, if you prefer arrays instead of Dictionaries:
ageCodePairs := dictSet collect: [ :eachDict | { eachDict at: 'age'. eachDict at: 'code' } ]
Just remember: since it's a Set, all operations respect its unordered nature. But the logic stays consistent with other Pharo collections—master do:, select:, and collect:, and you'll handle any Set task easily!
内容的提问来源于stack exchange,提问作者ludo

