What is the equivalent of foreach (with keys) in ActionScript - apache-flex

I am looking for the equivalent of a foreach loop with keys in Actionscript. In PHP this would be:
foreach($array as $key => $value)
{
}
I found two solutions that will work, but I am wondering if there is a better way to do this. The first solution is to use the for..in loop. Which gives you the keys, but you still have to use the key to access the correct element in your structure. For example:
for(var key:String in results)
{
trace(key + ": " + results[key]);
}
The second option is the for each..in loop, which I believe is new in AS3. With this solution, I can't tell what the keys are. For example:
for each(var row:* in results)
{
trace(row);
}
For the time being, I am going to use for..in. I am just looking for a better way.
Thanks,
Rob
Update: Speed is not a huge deal, because the array is never going to be extremely large. Order does matter, and I would like to get keys in the order of insertion. Here is an example of the array:
sites = {'site1': 34, 'site2': 52, 'site3': 66}
I would like to use the key as well as the value of each entry.
I want to keep my array structure as simple as possible. I could change the sites array above to look like:
sites = {{'name': 'site1', 'id': 34},
{'name': 'site2', 'id': 52},
{'name': 'site3', 'id': 66}}
However, I would rather not go this route, because it adds more dimensions to my array structure.

It depends on your object type. If you're using a Dictionary, you have:
DictionaryUtil.getKeys(myObject)
I wouldn't use for...in unless you're just dumping or purely want the keys and nothing else. It is an object so sort isn't guaranteed and will vary. If sorting isn't an issue, this (for...in or dictionary) is your best bet.
Grant speaks more on dictionary here: http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html.

for(var i:String in myArray) // loops through the items in the array
myArry[i] += 'new message will show'
for each(var i:String in myArray) // creates a copy of the array as it loops
myArray[i] += 'this change will not show outside the loop';
The later is great for if you need to minipulate the variables during the loop but want to preserve the original object for the rest of your program. Especially handy for formatting or translating values for a specific part of your program.

Related

Dart - Map vs Switch statement performance

In our flutter project, with use a lot of enums and extensions. Some of us write switch statements, some others use maps. I was wondering what practice is considered the best one in terms of time, memory etc ?
enum Animal { cat, dog, bird }
Switch statement:
extension AnimalExtension on Animal {
String get name {
switch (this) {
case Animal.cat:
return 'Cat';
case Animal.dog:
return 'Dog';
case Animal.bird:
return 'Bird';
}
}
}
Map:
extension AnimalExtension on Animal {
String get name => {
Animal.cat: 'Cat',
Animal.dog: 'Dog',
Animal.bird: 'Bird',
}[this];
}
Also, for the map method, is it better to create a static const Map instead of instantiating it on the fly at every call?
I wouldn't worry about speed for something this small, not unless it's at the heart of the inner loop of your computation.
The switch has the chance to be more time efficient, the map will likely have less code (it reuses the Map.[] code). The map should definitely be const.
If you want to optimize performance and code size, I'd go with:
String get name => const ['cat', 'dog', 'bird'][this.index];

need help understanding how to use dictionaries

I am a novice with regards to the swift 3 programming language though I am familiar basically with C++.
I am trying to learn to use dictionaries in Swift 3; which I believe are similar to hashes in C++. I have a dictionary with several key:value pairs in it.
I want to take a certain, single key (which I won't know in advance) and extract from that dictionary the corresponding value.
I know there will be a single key with that name, although the same value will be associated with keys of different names.
After extracting that value from the key:value pair of that dictionary then I want to store that single value in a variable as a string.
What type of code could do that?
I found some code that seems it might be helpful but I'm not sure and I'm not sure too how to use that code(how to write it actually) to make it perform as I wish.
extension Dictionary where Value: Equatable {
func someKeyFor(value: Value) -> Key? {
guard let index = indexOf({ $0.1 == value }) else {
return nil
}
return self[index].0
}
}
This is straight-forward dictionary access; no need to use extensions.
var myDictionary = [String:String]()
// At some point strings are put into the dictionary
// e.g. myDictionary["SomeKey"] = "SomeString"
// then you can say
if let someString = myDictionary[key] {
// You can now do something with someString
}
Keys and objects don't have to be strings, of course
I would suggest you read the Swift book from Apple in iBooks and try things out in in a Swift Playground in Xcode.

Meteor.js: Find all documents and return in reverse natural order

I am trying to return all documents in a collection, to use it with an {{#each}} in my template. My code looks like this:
return Answers.find({}, {sort: {$natural:-1}})
But the documents are returned in natural order (not reverse). Does anyone know why? I got the $natural selector from the MongoDB documentation, so I don't see what's wrong.
Can't tell why don't it returns in reverse order.
But you can create an array in the template helper method and return reverse of an array using array.sort() or array.reverse() functions.
For ex: Say you Answers collection looks like this:
Answers({ansNo: 1, ansBody: "body1"},
{ansNo: 2, ansBody: "body2"},
{ansNo: 3, ansBody: "body3"});
And the array to be returned is:
var AnswersArr = new Array();
then in your template helper :->
var tempCollection = Answers.find({});
tempCollection.forEach(function(data){
var obj = {ansNo: data.asnNo, ansBody: data.ansBody};
AnswersArr.push(abj);
});
AnswersArr.sort(function(a, b){return b.ansNo - a.ansNo;}); //sort in reverse order
return AnswersArr;
Sort isn't a parameter but a separate function to be called after find() on the resulting Cursor object. This is the method that the MongoDB documentation is referring to and works with drivers such as MongoJS:
return Answers.find().sort({$natural: -1});
It seems Meteor hasn't added the sort() function to their implementation of Cursor, so an alternate solution would be to sort by the _id field which is generated based on date (and hence insertion order):
return Answers.find({}, {sort: {'_id': -1}});
As a workaround you could do this:
return Answers.find().fetch().reverse();
I know it would be nicer to do it via the sort parameter, but I don't think it's possible right now.
I think you might be confusing definitions of 'natural order' here. One the one hand there is a natural sort order for letters/strings (A,B,C...) and numbers (1,2,3...).
But in the case of mongo, 'natural' refers to the order the data was written to disk. '{$natural:1}' returns 'documents in the order they exist on disk...' and, so '{$natural:-1}' reverses that (http://docs.mongodb.org/manual/reference/operator/meta/natural/).
So without the code that writes the data and some insight into how it was written to disk, we cannot test your hypothesis that it is not working correctly.

Filter Products in a Dynamic Way using LINQ

After hours of trying and searching, I think its time to share my problem with you right now.
Problem Definition :
I have a Dictionary of KeyValuePairs(named filterPool) which includes an integer (PropertyID) and a string(McValue). What I am trying to do is filtering products depending on those KeyValuePairs and return them as a DataTable/List.
You may consider this as building dynamic "Where ... And .." clauses as SQL.
Here is the code that I am using :
foreach (KeyValuePair<int, string> filter in filterPool)
{
products = products.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value));
}
return products.ToDataTable();
The problem is the foreach loop above seems to work only once, for the latest KeyValuePair available in the Dictionary.
As far as I could find on Stackoverflow, the closest solution to my problem was : this one, also using a Dictionary of values for filtering
There must be a way to achieve the goal of filtering using Dictionary and LINQ; or there's a huge thing that I am missing/ignoring to see somehow.
Hope the problem given is clear enough for all,
Thanks
^^
This is a closure issue. You can solve it by making a temporary:
foreach (KeyValuePair<int, string> filterTmp in filterPool)
{
var filter = filterTmp; // Make a temporary
products = products.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value));
}
return products.ToDataTable();
For details on what's happening, see Eric Lippert's post Closing over the loop variable considered harmful.
Also note that this behavior has changed for C# 5. In C# 5/VS2012, this code would work as expected.
You're overwriting your products collection on every iteration of your foreach. I'm not sure what the data type on your collection is, but you'll want to do something like this in your foreach instead:
products.AddRange(products.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value)));
I'm not sure if that makes sense, but it seems like you're trying to create a collection full of products that match your filterPool.
I think that it's better solved with aggregate:
return filter
.Aggregate(products, (acc, filter) => acc.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value)));
.ToDataTable();

How can I achieve this search condition?

I want to implement some search condition like the below which I want to make in best optimized way, how can I achieve this?
switch (e.CommandName)
{
case "DRESS":
chkItem.Items.Clear();
chkItem.DataSource = cDressing.GetAllDressingDetail(cWebUtil.CurrClientID);
chkItem.DataTextField = "Description";
chkItem.DataValueField = "DressingID";
chkItem.DataBind();
CurrBtnMode = btnMode.Dressing;
// ModalPopupExtender1.TargetControlID = ((Button)grdOrder.Rows[currItem.OrderItemID -1].FindControl("btnDress")).ID.ToString();
if (currItem.DressingItems.Count > 0)
{
foreach(cOrderItemDressing itemDress in currItem.DressingItems )
{
// I want here to apply condtion for those chkItem object's DressingID exist in the itemDress objets's DressingID should
// have checked state in checkbox list to be populated.
}
}
ModalPopupExtender1.Show();
Is you goal to check the items in the chkItem.Items that have a matching item in the currItem.DressingItems collection? I'm not sure if this is what you want to get, but you can try this:
...
//uncheck all the items first (if you need it)
foreach (var item in chkItem.Items)
{
item.Checked = false;
}
foreach(cOrderItemDressing itemDress in currItem.DressingItems )
{
bool chkItemFound = false;
foreach (var item in chkItem.Items)
{
//if the item is found, make it checked
if (item.DressingID == itemDress.DressingID)
{
item.Checked = true;
chkItemFound = true;
break;
}
}
}
I haven't tested this yet, so if you've got some issues when using it, just let me know.
Update
You asked if it's the most optimized way of solving the issue. I would say there are more optimized methods, but I wanted to keep the code simple to just show the solution.
It may be sufficient, but it depends on how many items does each of the collections contain.
I suppose that a quite simple way to optimize it would be preventing so many items comparisons by removing an item you've already found (because it's not needed in further comparisons). This way the collection can shrink with each loop iteration, making it work faster. You may need, however, to create a copy of the collection you want to modify in order to have acces to its original form (and keep note that allocation of this array can take some time).
Another way would be using sorted collections and implementing some kind of searching algorithm for them. This will make the searching process itself faster, but needs some additional time to sort the collections (sorting can also be implemented by creating collection in a sorted form, so no sorting is needed later).
There are probably some other ways to do it, but it can depend on the details of other parts of your application and amount of data you want it to work with.

Resources