Ways to keep a collection ordered in Backbone? - backbone.js

I have a collection which uses comparator function to sort its models.
The models have a rank-attribute used for sorting them.
In my model view I have a button for upgrading and downgrading the rank attribute by one. By listening to the collections change event I can call "sort" every time the rank attribute of a model is changed, thus reordering the the list.
The problem is keeping the rank unique - now I'm just changing the rank value of a single model, which will not affect the other models.
For example:
item A, rank 1
item B, rank 2
item C, rank 3
To:
item A, rank 1
item B, rank 1
item C, rank 3
Is there a smart (backbone) way of changing the ranks of the rest of the models?
If it needs to be done manually, then what is a good strategy for doing it? I'm currently changing the model from the model's view and listening to change in collection's view so there's is no obvious way to affect the ranks of the adjacent models.

Related

How to sort (through filters) a table based on two different columns?

I have a table in Google sheets which I need to filter on a primary and a secondary column An analogous example would be points of different teams in a football league. The primary filter would be decreasing values of total points in the season. If the total points of two teams are the same, then the secondary filter would kick in which would be based on a decreasing value of goal difference.
So, let's say teams A and B have the same points. But B has a superior goal difference. So B should be placed higher than A.
Is there a way this can be done without complicated functions?
function is pretty simple:
=SORT(A1:C, 2, 0, 3, 0)
2, 3 being columns and 0 for decreasing

Retrieve Index by Values From an Array Through a ComboBox

I have a transposed dynamic n x 2 array that is used to populate a combobox. The primary column alone is not descriptive enough to identify rows uniquely. I would like to use the row index to identify the untransposed column uniquely. Using both columns in the array could also be used for this but may prove problematic down the line. This question is closely related to this question.
I have used Me.cbo.ListIndex = 0 to retrieve the index value. Ideally, I'd like to assign the index of the row chosen in the combobox to a variable. The ultimate goal is to use the index in two ways:
For finding the correct column to use in future calculations
As a method for comparison against another combobox that uses the same array in order to ensure that the same row has not been chosen in both comboboxes
To visually illustrate the above, the original data looks like this:
a b c b
1 2 3 4
A B C B
The transposed array looks like this:
A 1
B 2
C 3
B 4
I would like to be able to make a distinction between selecting B2 and B4, ideally by preserving and comparing index 1 and 3 respectively (0-based).
ListIndex is from the documentation. There is no documentation that I could find about retrieving the index from the name except where the value in the selection is unique. Any Help is greatly appreciated

Distinct count over multiple dimensions

I am completely new to MDX.
I have to implement a set of indicators. Example:
Discharges, for patients ages 18 years and older with either:
- any-listed ICD-9-CM procedure codes for esophageal resection; or
- any-listed ICD-9-CM procedure codes for gastrectomy and any-listed ICD-9­ CM diagnosis codes for esophageal cancer. Link to complete spec here.
Thus I think I need to create a measurement (lets call is countX) that counts the number of facts (discharges) that belong to some computed set OR that belong to some other computed set. If a fact belongs in both sets, then it should only be counted once.
A set definition may contain crossjoins and filters over multiple dimensions.
The idea is then to be able to slice countX along any dimensions (ideally including those used to compute the sets).
I already learned that the UNION operator only works when joining sets over the same dimension. So, is my approach feasible to do using MDX? Maybe I can formulate the problem in a different way to somehow make use of calculated members or so?
Or would it be better to create specific fact or dimension tables populated with the correct information using SQL?
Thanks
You can UNION two sets of different dimensionality by creating tuples that use both dimensions, but basically ignore one in one case, and the other in the other case.
I don't know your cube or your data, so I'm going to use very simple psuedocode. Say you want to get all widgets that are red and all widgets that are small.
Another way to think is: I want all widgets that are red, regardless of their size, and I want all widgets that are small, regardless of their color.
So psuedo-MDX for expressing this would be:
({[dimColor].[&Red]}, {[dimSize].[All]})
+
({[dimColor].[All]}, {[dimSize].[&Small]})
Get the specific member(s) you want from Dimension A, CrossJoined with ALL members of Dimension B. And then you can UNION that with ALL members of Dimension A, CrossJoined with the specific member(s) you want from Dimension B, because you have met UNION's requirement that the two sets have the same dimensionality.

Hiding vars in strings VS using objects with properties?

So, I've got a word analyzing program in Excel with which I hope to be able to import over 30 million words.
At first,I created a separate object for each of these words so that each word has a...
.value '(string), the actual word itself
.bool1 '(boolean)
.bool2 '(boolean)
.bool3 '(boolean)
.isUsed '(boolean)
.cancel '(boolean)
When I found out I may have 30 million of these objects (all stored in a single collection), I thought that this could be a monster to compile. And so I decided that all my words would be strings, and that I would stick them into an array.
So my array idea is to append each of the 30 million strings by adding 5 spaces (for my 5 bools) at the beginning of each string, with each empty space representing a false bool val. e.g,
If instr(3, arr(n), " ") = 1 then
'my 3rd bool val is false.
Elseif instr(3, arr(n), "*") = 1 then '(I'll insert a '*' to denote true)
'my third bool val is true.
End If
Anyway, what do you guys think? Which way (collection or array) should I go about this (for optimization specifically)?
(I wanted to make this a comment but it became too long)
An answer would depend on how you want to access and process the words, once stored.
There are significant benefits and distinct advantages for 3 candidates:
Arrays are very efficient to populate and retrieve all items at once (ex. range to array and array back to range), but much slower at re-sizing and inserting items in the middle. Each Redim copies the entire memory block to a larger location, and if Preserve is used, all values copied over as well. This may translate to perceived slowness for every operation (in a potential application)
More details (arrays vs collections) here (VB specific but it applies to VBA as well)
Collections are linked lists with hash-tables - quite slow to populate but after that you get instant access to any element in the collection, and just as fast at reordering (sorting) and re-sizing. This can translate into a slow opening file, but all other operations are instant. Other aspects:
Retrieve keys as well as the items associated with those keys
Handle case-sensitive keys
Items can be other collections, arrays, objects
While keys must be unique, they are also optional
An item can be returned in reference to its key, or in reference to its index value
Keys are always strings, and always case insensitive
Items are accessible and retrievable, but its keys are not
Cannot remove all items at once (either one by one, or destroy then recreate the Collection
Enumerating with For...Each...Next, lists all items
More info here and here
Dictionaries: same as collections but with the extra benefit of the .Exists() method which, in some scenarios, makes them much faster than collections. Other aspects:
Keys are mandatory and always unique to that Dictionary
An item can only be returned in reference to its key
The key can take any data type; for string keys, by default a Dictionary is case sensitive
Exists() method to test for the existence of a particular key (and item)
Collections have no similar test; instead, you must attempt to retrieve a value from the Collection, and handle the resulting error if the key is not found
Items AND keys are always accessible and retrievable to the developer
Item property is read/write, so it allows changing the item associated with a particular key
Allows you to remove all items in a single step without destroying the Dictionary itself
Using For...Each...Next dictionaries will enumerate the keys
A Dictionary supports implicit adding of an item using the Item property.
In Collections, items must be added explicitly
More details here
Other links: optimizing loops and optimizing strings (same site)

Network of dependent values - how to only recalculate them once each?

I'm hoping one of you guys can figure this out.
I have an array containing lots of objects. Each object in the array contains two things:
A value which can change.
A list of zero or more of the other objects in my array which, if their values change, then this object needs to recalculate it's value. This can cascade many times from object to object, but there is no looping of dependencies.
I believe this is called a network (like a tree, but with multiple parents). Specifically, this is a Directed Acyclic Graph.
What I'm doing right now is this: when I change an object's value, I check every object in the array to see if it depends on the object I just changed. If it does, then I tell this child object to recalculate. Then the child tells it's children in the same way, and so on.
This works (the values update correctly), but it's very very slow when a change is made that cascades wide and deep. This is because if an object has many parents that change, it recalculates again for each one, and also tells it's children to recalculate each time, so they get several messages from just one parent. This quickly snowballs until many objects are recalculating dozens of times.
What's the best way to only recalculate each object once, after all of it's parents has recalculated?
Thanks for your help.
It sounds like you want a Topological Sort of a Directed Acyclic Graph. See for example http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Graph/DAG/
If your graph isn't constantly changing you should be able to simply sort it once and from then on you can execute your updates in order from left to right knowing that at each step the set of nodes you will be adding to the list to be computed are all to the right of the current position. There's a few ways you could optimize that, maybe store them in a simple heap, pick the leftmost value off each time, recalculate it and add back any nodes it references, or as someone else has suggested, if the full dependency graph is small enough, just store it on each node in the order in which it needs to be calculated (as found using the Topological Sort).
Create an acyclic digraph with vertices given by the nodes in your array and an edge i --> j whenever a change in i necessitates a recalc of j (i.e. i is in the list for object j). The graph is acyclic iff your process is finite.
Now, when i changes, do a breadth first search to recalculate dependent nodes. At first pass, gather all nodes j such that i --> j. Recalculate those j. At the second pass, take each j that changed and get its dependents j --> k. Then recalculate those k at once. Continue by taking all the dependents of the ks that changed, and so on, until there are only leaves.
This requires you to keep a list of neighbors, which is the inverse of the information that you have. So you need to do one pass to get the directed edges (fill an array so that entry i has the array of all j for which i --> j).
When a value gets updated, create a list of the other elements whose values still need to be recalculated. Before recalculating the value of an element in this list, make sure that none of the other elements on which it depends are also in the list. This will ensure that an element will only get recalculated once. Since there are no circular dependencies, there will always be at least one element in the list of elements to be recalculated which has already had all of its dependent elements recalculated.
Pseudo code:
Create a set S
Add initially updated element to S
while S is not empty
remove an element X from S whose value does not depend on any other elements in E do not exist in S
recalculate X's value and add any elements that depend on X's value to S

Resources