Getting a key in the ActionScript Dictionary - actionscript

I am using a Dictionary in ActionScript as a queue, sort of, still reading most of the time as an associative container, but I need one time to make a loop to run through the whole dictionary, such as for (var key:String in queue) . Inside this for loop I perform some actions on an element and then call delete on that key.
My issue is that I would like to wait for an Event before fetching the next element in this queue. Basically my for loop runs too fast. I would like to fetch the next key all the time, but I know there is no built in method.
A solution I thought is to add a break to the loop, as the for.. in will automatically fetch the next key, but it would be a loop which always executes one time, simply to fetch the next key. This sounds a bit counter intuitive.
I hope my problem makes sense and I really look for some better ideas than what I currently have. Thanks for your help!
Rudy

haha, that is an interesting problem indeed. there doesn't seem to be any way of retrieving a list of keys from the dictionary, short of the method you've outlined. an alternative would be caching the list of the keys on the first run, but that might get out of sync and is quite untidy anyway.
i guess my main question is why can't you do what you want to do with a list? if you need 2 values (eg strings) then just make a list of objects :)

var lInfo:Object = ObjectUtil.getClassInfo(lDict);
for each(var lProperty:String in lInfo.properties)
{
var lItem:* = lDict[lProperty];
}

Related

Adding Items from Lists to Dictionaries in Apple Shortcuts

I have this Shortcut which queries a Notion database, then fetches the IDs and titles of pages from the database and turns them into key : value pairs.
I want to add those key : value pairs to the dictionary shown at the top of the screenshot. The problem is, even though I can see that I'm adding to the dictionary inside the Repeat With Each Item loop -
When I check the contents of my Categories dictionary at the end of the Shortcut, those entries haven't been saved.
I have seen this answer, which appears to solve the same problem. But when I implement it and then check the contents of the variable inside the loop, nothing is even being set here.
I'd be very grateful for any pointers here.
I figured out the problem - I needed to set the dictionary as a variable outside the loop -
And then I can update the dictionary inside the loop -
I don't know why that works but it does ¯\(ツ)/¯

Parse SaveInBackgroundWithBlock takes a lot of time

I have a parse class(named "Story") with following columns:
contents - Array of Pointers to Media class
creator - User pointer
lastPosted - Date
title - String
users - array of pointers to User class
I am trying to update a PFObject from "Story" class like this
storyObject.addUniqueObjectsFromArray(selectedFriends, forKey: "users")
storyObject.setObject(createStoryTextField.text, forKey: "title")
storyObject.saveInBackgroundWithBlock({ (succeed: Bool, error: NSError?) -> Void in
hud.hide(true)
})
In some cases the completion block takes a lot of time to complete. By debugging, I have found that the more objects in the "contents" column, the longer it takes. But I haven't even updated the "contents". All the values in the code are not nil. I checked for that too. Any help would be appreciated. Thanks.
This is potentially expected behavior. In general when you put something on a background thread (like saveInBackgroundWithBlock is almost definitely doing) it will take a lot longer to complete than if you call it on the main thread. If you need it to return quickly and don't mind blocking the UI, you can use the save: method.
You also may want to check to see how many requests you are making simultaneously as this may slow down each one.
Finally, if you want to customize the network behavior of Parse more than you already do, you can just use the REST API and make all your own network calls (using NSURLSession or a third party library like AFNetworking.)

Parse.com findObjects() get data

I need to run a SYNCHRONOUS call to parse.com. This is what I got:
var query = PFQuery(className:"myClass")
query.whereKey("groupClassId", equalTo:self.currentGroupId)
query.selectKeys(["objectId", "firstName", "lastName"])
self.arrayCurrentData = query.findObjects() as Array<myData>
This return the correct number of rows from parse.com and fills up my local array. But how can I extract the data from the array? If I look at the array at runtime it shows that all the data I need is in 'serverData' in self.arrayCurrentData.
Normally if I loop an async(findObjectsInBackgroundWithBlock) filled array I would ask
self.arrayCurrentData[i].lastName
to get the lastName, but that is not the case in the sync array. There I can't ask directly for values (or so it seems).
Anyone who know what I am talking about and how to get data synchronous from parse.com?
Get the PFObject's attributes with valueForKey(). This is true whether or not the object was fetched synchronously. In other words...
self.arrayCurrentData[i].valueForKey("lastName")
EDIT - This approach generates a compiler message because you've typed the response as Array<myData>. But find returns PFObjects, so ...
self.arrayCurrentData = query.findObjects() as [PFObject]
... is the correct cast. I'm not a swift speaker, but the expression self.arrayCurrentData[i].lastName pleases the compiler because arrayCurrentData[i] is typed as myData. But this fails at run time because the real returned objects are PFObjects.
As an aside, I'd take a hard look at the rationale for fetching synchronously. I can't think of a case where its a good idea on the main thread. (off the main okay, but then you've already opted for asynch vs. the main, and the block-based methods provide a good way to encapsulate the post-fetch logic).

Cocos 2D is it possible to add more CCActions to a node during execution?

I have a node in my game that I'd like to be able to queue up additional actions after it's already started executing. Is this even a possibility?
Could you clarify? You can add actions to a sprite that is already performing actions. If you're looking to run an action at a later time, you can use scheduleOnce; this will allow you to execute a method after a specified duration.
Yes, that's possible. Look into CCSequence (series of actions running in a sequence) and CCSpawn (spawn new actions, specifically useful when using a sequence).
The only thing you shouldn't do is to run two actions of the same kind at the same time. For example more than one CCMove* or CCTint* actions. This is because they'll override each other's changes, which will lead to strange behavior.
I dont think you can modify the sequence when in progress, but you could add a 'CCCallXYZ' action to schedule 'one shot' a class method where you could take any action, including defining a new sequence of actions for your object. Timing and control could be tricky :)
just an idea, havent tried yet.
when you build your CCSequence as a last action put a CCCallBlock, inside the block you will have e machinism to get you additional action you added at runtime.
i'm writing pseudocode on the fly here.
the block appendend as an action would looks something like this:
{
CCSequence *additionalActions = [MyRuntimeActionClass getAdditionalActionsForObject:spriteRunningTheAction];
if(additionalActions)
[spriteRunningTheAction runAction:additionalActions]
}
if we have stored additional actions for the object, we get the sequence and we run it.
additionalActions can store a Dictionary with key the address of the object to run on (spriteRunningTheAction) and value the CCSequence to append

Erlang and the records

What is wrong in this code?
I was expected "titi" in person.name but I still have "toto"!
More explicitly, how to modify a record in a function?
init1()->
S=#person{name="toto"}, %record creation and field setting
fct(S),
io:format("~s~n",[S#person.name]).
fct(R)->
R#person{name="titi"}. %record updating
You need to get a result of fct():
init1()->
S=#person{name="toto"}, %record creation and field setting
S2 = fct(S), % Get updated record
io:format("~s~n",[S2#person.name]).
fct(R)->
R#person{name="titi"}. %record updating
Bertaud, I think you are getting ahead of yourself a bit. You really need to understand the basics of immutability before you write any more code. (i.e. "variables" do not vary : you can only assign a value to them once.) I suggest you read the free online guide "Learn You Some Erlang For Great Good", at http://learnyousomeerlang.com/. The section that covers the basics of variables is http://learnyousomeerlang.com/starting-out-for-real#invariable-variables.
It is impossible to stress too much that all data in Erlang is immutable. So to do something like in your original question you need to modify it like #hdima did. The record is not updated but rewritten. In the same way there is no global data in Erlang, all data belongs to a process. This is even true of ETS tables as they basically behave like a process, albeit a built-in one without explicit communication.
So if you use the process dictionary or an ETS table the data itself can never be updated, only the dictionary/table. This means that to modify some data in the dictionary/table you basically have to:
"Read" the data
Update the data making new data
"Write" the new back into the dictionary/table
Without writing the new data back into the dictionary/table it will be lost, as your new data was.
Within fct(), you're not mutating the record, but you're returning a new value for the record, which needs to be used further. If you're calling fct(S), without handling the return value, then you'll lose that new value ("titi").

Resources