Pharo dictionary - smalltalk

I have an issue and this is the result when i call one method in my code.
t do:[:i |
dict := Dictionary newFrom:{t->items}.
].
t is an
OrderedCollection(#name #lastName #birthDate)
and items too. items an OrderedCollection('cs0yh1n1b2bm0wps16uvy7tfi' 'cs0yh1k1t3bgdszfupe407qdg' 21 April 1975)
a Dictionary [1 item] (an OrderedCollection(#name #lastName #birthDate)->an OrderedCollection('cs0yh1n1b2bm0wps16uvy7tfi' 'cs0yh1k1t3bgdszfupe407qdg' 21 April 1975).
I would like to obtain a gender dictionary
a Dictionary (#name->'cs0yh1n1b2bm0wps16uvy7tfi' #lastNamename->'cs0yh1k1t3bgdszfupe407qdg' #birthDay->21 April 1975)
how can i do this please ?

You are creating a new Dictionary each time through the loop. You need to create a new (empty) Dictionary before the loop and add each element using #'at:put:'. If you want to map index 1 in t to index 1 in items, then you need to have a counter. Perhaps 1 to: t size do: [:i | ...].
You are asking a lot of questions about Smalltalk and we are delighted to have you learning it. Have you tried spending a few hours studying a book or taking a course? I recommend the Pharo Mooc, some Pharo books, or some Smalltalk books.

Related

Is there really no predefined dynamic 2d container in Smalltalk? Do I have to make my own?

I need a dynamic 2d container and I was suprised that I could not find anything usefull in the Collections. So I made my own in oldskool fashion but somehow I feel like there must be somthing im missing. The whole concept in smalltalk pharo is based on using their stuff instead of having to build your own.
OK, so you want to have a collection of objects (morphs in your case) arranged by rows and columns. Here is one way to do this
Initialization: Create an instance variable in your class for holding the objects, and initialize it as:
morphs := OrderedCollection new
Addition: Place new objects in your collection by means of a method like this one
placeMorph: morph atRow: i column: j
| row |
row := morphs at: i ifAbsentPut: [OrderedCollection new].
j - row size timesRepeat: [row add: nil].
row at: j put: morph
Note that by adding nil exactly j - row size times (which could be <= 0) ensures the existence of a slot at row i column j.
Retrieval: Get the object at a given position in the grid or nil
morphAtRow: i column: j
| row |
row := morphs at: i ifAbsent: [^nil].
^row at: j ifAbsent: [nil]
Another possibility would be to use a Dictionary, which could make sense if the grid is large and sparse. In that case you could do the following
Initialization
morphs := Dictionary new
Addition
placeMorph: morph atRow: i column: j
morphs at: i -> j put: morph
Retrieval
morphAtRow: i column: j
^morphs at: i -> j ifAbsent: [nil]
Note that I've used associations i -> j for the keys. Another possibility would have been to use pairs {i.j}.
Pharo has Matrix class. That's pretty much a 2d container, unless you are talking about something else I do not understand :)

Nested arrays of methods/data

I have a question regarding nested arrays of objects.
I’m writing a simple objective c program (I’m a beginner) and I was wondering whether it is advisable to structure an array in such a way that not only are all the individual batting scores be logged (data), but also methods embedded in the nested arrays could be used to interrogate the this data.
For example the line below is easily readable (even for those who are not cricket fans!)
Team1.Over[2].BowlNumber[3].score = 6
Team 1 scored a 6 during the 3rd bowl in the 2nd Over.
I would also like to do something like the following where I can use a method to interrogate the data. The method line below would just cycle through the scores within BowNumber[] and total the scores up
Total =  Over[2].TotalForAmountForOver()
I could set up and manage all the arrays from within main() , but its much easier to read if I can embed as much as possible within the structure. 
Is this a common approach?
 
Haven't seen many examples of fairly complicated embedded arrays of data and methods…. 
You'd easily be able to achieve this by making Over cant Bowl classes that each wrap an NSMutableArray object. e.g.
- (void)getOverNumer:(int)index {
return [overs objectAtIndex:index];
}
You'd then access it like this:
[[team1 getOverNumber:2] getBowlNumber:2].score = 6;
int total = [[team1 getOverNumber:2] totalForAmountForOver];
You'd implement totalForAmountForOver as a method within your Over class.

Are my container's children starting at index -1 or 0?

I'm getting some behavior with a container object's children I just don't understand.
I'm making four display objects children of an mx:Canvas object. When I call getChildren(), I see them all in order, right where I think they should be:
1
2
3
4
The fun begins when I call swapChildrenAt(0,1); that's supposed to swap the positions of 1 and 2, but instead I wind up with:
MYSTERY_OBJECT_OF_MYSTERY
2
3
4
So, where did 1 go? Why, it's at position -1, of course.
getChildAt(-1): 1
getChildAt(0): MYSTERY_OBJECT_OF_MYSTERY
getChildAt(1): 2
getChildAt(2): 3
getChildAt(3): 4
FWIW, MYSTERY_OBJECT_OF_MYSTERY is a 'border'. Don't know how it got there.
Regardless, I find it baffling that getChildAt() and swapChildrenAt() are apparently using different starting indexes. Can anybody shed some light on this behavior?
You appear to be swapping the index of the display Objects instead of passing the display Objects at those location themselves.
The official documentation says
"swapChildren(child1:DisplayObject, child2:DisplayObject):void" therefore the index of the Display Objects themselves cant be used.
I hope this solves your problem.

Comparing two NSMutableDictionaries

Hello fellow Computer People!
I could do this myself, but was just wondering if there was a more efficient way that I haven't though of:
I have two NSMutableDictionaries. Let us use these as an example:
Dictionary 'Madrid'
Bob : 54
Thomas : 32
Frank : 20
Dictionary 'Barcelona'
Bob : 1100
Thomas : 32
Ed : 55
Frank : 20
What I want to get from comparing these two is:
The fact that the value for Bob is different between the two Dictionaries
That Frank has a value in Barcelona, but was not at all in Madrid.
This is for monitoring a sort of time series to see if any activity is happening from one iteration to the next.
Obviously this should be dealt with in Objective-C.
Any opinions on the most efficient way of doing this?
Thanks so much!
Probably the best way would involve a simple loop through one of the dictionaries, then check to see if you missed any keys in the other dictionary. Since dictionaries are involved it would only be O(N)
Objective-C supports isEqualToDictionary:
Usage:
if ([(NSDictionary *)mutableDictionary1 isEqualToDictionary:(NSDictionary *)mutableDictionary2]) {

Algorithm for 'Syncing' 2 Arrays

Array 1 | Array 2
=================
1 | 2
2 | 3
3 | 4
5 | 5
| 6
What is a good algorithm to 'sync' or combine Array 2 into Array 1? The following needs to happen:
Integers in Array 2 but not in Array 1 should be added to Array 1.
Integers in both Arrays can be left alone.
Integers in Array 1 but not in Array 2 should be removed from Array 1.
I'll eventually be coding this in Obj-C, but I'm really just looking for a pseudo-code representation of an efficient algorithm to solve this problem so feel free to suggest an answer in whatever form you'd like.
EDIT:
The end result I need is bit hard to explain without giving the backstory. I have a Cocoa application that has a Core Data entity whose data needs to be updated with data from a web service. I cannot simply overwrite the contents of Array 1 (the core data entity) with the content of Array 2 (the data parsed from the web into an array) because the Array 1 has relationships with other core data entities in my application. So basically it is important that integers contained in both Arrays are not overwritten in array one.
Array1 = Array2.Clone() or some equivalent might be the simplest solution, unless the order of elements is important.
I'm kind of guessing since your example leaves some things up in the air, but typically in situations like this I would use a set. Here's some example code in Obj-C.
NSMutableSet *set = [NSMutableSet set];
[set addObjectsFromArray:array1];
[set addObjectsFromArray:array2];
NSArray *finalArray = [[set allObjects] sortedArrayUsingSelector:#selector(compare:)];
(Assuming this is not a simple Array1 = Array2 question,) if the arrays are sorted, you're looking at a single O(n+m) pass over both arrays. Point to the beginning of both arrays, then advance the pointer containing the smaller element. Keep comparing the elements as you go and add/delete elements accordingly. The efficiency of this might be worth the cost of sorting the arrays, if they aren't already such.
In my approach, You will need Set data structure. I hope you can find some implementations in Obj-C.
Add all elements of Array1 to Set1
and do the same for Array2 to Set2.
Loop through elements of Array1.
Check if it is contained in Set2
(using provided method.) If it is
not, removed the element from Set1.
Loop through elements of Array2. If it
is not existed in Set1 yet, add it
to Set1.
All elements of Set1 is now your "synced" data.
The algorithm complexity of "contains","delete", and "add" operation of "Set" on some good implementation, such as HashSet, would give you the efficiency you want.
EDIT: Here is a simple implementation of Set assumed that the integer are in limited range of 0 - 100 with every elements initialized to 0, just to give more clear idea about Set.
You first need to define array bucket of size 101. And then for ..
contains(n) - check if bucket[n] is 1 or not.
add(n) - set bucket[n] to 1.
delete(n) - set bucket[n] to 0.
You say:
What is a good algorithm to 'sync' or combine Array 2 into Array 1? The following needs to happen:
Integers in Array 2 but not in Array 1 should be added to Array 1.
Integers in both Arrays can be left alone.
Integers in Array 1 but not in Array 2 should be removed from Array 1.
Here's some literal algorithmic to help you (python):
def sync(a, b):
# a is array 1
# b is array 2
c = a + b
for el in c:
if el in b and el not in a:
a.append(el) # add to array 1
elif el in a and el not in b:
a.remove(el) # remove from array 1
# el is in both arrays, skip
return a # done
Instead of "here's what needs to happen", try describing the requirements in terms of
"here's the required final condition". From that perspective it appears that the desired end-state is for array1 to contain exactly the same values as array2.
If that's the case, then why not the equivalent of this pseudocode (unless your environment has a clone or copy method)?
array1 = new int[array2.length]
for (int i in 0 .. array2.length - 1) {
array1[i] = array2[i]
}
If order, retention of duplicates, etc. are issues, then please update the question and we can try again.
Well, if the order doesn't matter, you already have your algorithm:
Integers in Array 2 but not in Array 1 should be added to Array 1.
Integers in both Arrays can be left alone.
Integers in Array 1 but not in Array 2 should be removed from Array 1.
If the order of the integers matter, what you want is a variation of the algorithms that determine the "difference" between two strings. The Levenshtein algorithm should suit your well.
However, I suspect you actually want the first part. In that case, what exactly is the question? How to find the integers in an array? Or ... what?
Your question says nothing about order, and if you examine your three requirements, you'll see that the postcondition says that Array2 is unchanged and Array1 now contains exactly the same set of integers that is in Array2. Unless there's some requirement on the order that you're not telling us about, you may as well just make a copy of Array2.