How to write a multidimensional array in APEX - apex-code

I have a two dimensional array in Java:
private static final string[][] namestr = { { John, Mark, David,
}, { Peter, Ken, Mary,
}, { Fisher, Alice, Chris,
}, { Tod, Jen, Joe, Morton
}};
How can I write this Two dimensional array in Apex?
I still need to keep it as a two dimensional array with [4][3],
Thanks

You can have a list of lists. I think the proper term is "jagged array" as opposed to "multidimensional array". What I mean is that it's up to you to make sure each internal list has same size; language itself won't enforce this in any way. But since your last row has 4 items instead of 3 looks like you're OK with that.
http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_collections_lists.htm
Because lists can contain any collection, they can be nested within
one another and become multidimensional. For example, you can have a
list of lists of sets of Integers. A list can contain up to four
levels of nested collections inside it.
List<List<String>> names = new List<List<String>>{
new List<String>{'John', 'Mark', 'David'},
new List<String>{'Peter', 'Ken', 'Mary'},
new List<String>{'Fisher', 'Alice', 'Chris'},
new List<String>{'Tod', 'Jen', 'Joe', 'Morton'}
};
System.debug(names[1]);
System.debug(names[1][2]);
There's no size limit, standard stuff like heap space limit applies. If you plan to pass them to Visualforcethe limit is 1000 items though (10K if your page has readonly attribute set).

Related

How do we find the most similar objects from the list of objects?

Suppose I have a list A containing 1000 objects of same class with different properties.
How can I extract the list of most similar objects corresponding to a certain set of property values?
By similar I mean having least difference in property values?
For Example:
I have a class like:
class Cat{
string breed;
string color;
int age;
int weight; // in kgs
}
There are many objects in the list ( more than 1000 ) like:
Cat('Persian', 'white', 2, 5)
Cat('Bengal', 'spotted brown', 1.5, 3)
Cat('Siamese', 'dark gray/white', 2, 4)
Cat('Sphynx', 'light gray', 3, 8)
Cat('Ragdoll', 'white', 1, 2)
Now I want to sort the above list on the basis of maximum similarity to another object say:
Cat('Chartreux', 'dark gray', 2.5, 6)
How can I compare multiple values at once with lowest possible running time?
Consider all the properties as of equal importance.
1 Create a method that compare 2 objects of the class.
2 Sort the array based on this comparison method.
The most similar elements will stay together in the sorted array.

What is the most appropriate data structures for these cases?

I am working on a program and I'm considering which data structure is most appropriate.
I have the following class -
public class item{
String name;
int value;
public item(String name, int value){
this.value = value;
this.name = name;
}
}
I have two cases -
To store a large amount of items and retrieve the top n amount of items while new items are being added and old items have their values updated.
To store all the items and retrieve top n amount of items without any new items being added or old items being updated.
I'm trying to achieve the best case time complexity for both cases.
I have thought about storing all items in a map for look up by their name, and in a maxheap, then removing n number of items from the top, storing them, then adding them back to the stack.
I've looked at priority queues and binary search trees as options, would either of these be more suitable? or are they any other structures that would fit either of these cases?
If name is unique you can use IDictionary. It is pretty fast for this uses

Year over Year Stats from a Crossfilter Dataset

Summary
I want to pull out Year over Year stats in a Crossfilter-DC driven dashboard
Year over Year (YoY) Definition
2017 YoY is the total units in 2017 divided by the total units in 2016.
Details
I'm using DC.js (and therefore D3.js & Crossfilter) to create an interactive Dashboard that can also be used to change the data it's rendering.
I have data, that though wider (has ~6 other attributes in addition to date and quantity: size, color, etc...sales data), boils down to objects like:
[
{ date: 2017-12-7, quantity: 56, color: blue ...},
{ date: 2017-2-17, quantity: 104, color: red ...},
{ date: 2016-12-7, quantity: 60, color: red ...},
{ date: 2016-4-15, quantity: 6, color: blue ...},
{ date: 2017-2-17, quantity: 10, color: green ...},
{ date: 2016-12-7, quantity: 12, color: green ...}
...
]
I'm displaying one rowchart per attribuet such that you can see the totals by color, size, etc. People would use each of these charts to be able to see the totals by that attribute and drill into the data by filtering by just a color, or a color and a size, or a size, etc. This setup is all (relatively) straight forward and kind of what DC is made for.
However, now I'd like to add some YoY stats such that I can show a barchart with x-axis as the years, and the y-axis as the YoY values (ex. YoY-2019 = Units-2019 / Units-2018). I'd also like to do the same by quarter and month such that I could see YoY Mar-2019 = Units-Mar-2019 / Units-Mar-2018 (and the same for quarter).
I have a year dimension and sum quantity
var yearDim = crossfilterObject.dimension(_ => _.date.getFullYear());
var quantityGroup = yearDim.group.reduceSum(_ => _.quantity);
I can't figure out how to do the Year over Year calc though in the nice, beautiful DC.js-way.
Attempted Solutions
Year+1
Add another dimension that's year + 1. I didn't' really get any further though because all I get out of it are two dimensions whose year groups I want to divide ... but am not sure how.
var yearPlusOneDim = crossfilterObject.dimension(_ => _.date.getFullYear() + 1);
Visually I can graph the two separately and I know, conceptually, what I want to do: which is divide the 2017 number in yearDim by the 2017 number in YearPlusOneDim (which, in reality, is the 2016 number). But "as a concept is as far as I got on this one.
Abandon DC Graphing
I could always use the yearDim's quantity group to get the array of values, which I could then feed into a normal D3.js graph.
var annualValues = quantityGroup.all();
console.log(annualValues);
// output = [{key: 2016, value: 78}, {key: 2017, value: 170}]
// example data from the limited rows listed above
But this feels like a hacky solution that's bound to fail and not benefit from all the rapid and dynamic DC updating.
I'd use a fake group, in order to solve this in one pass.
As #Ethan says, you could also use a value accessor, but then you'd have to look up the previous year each time a value is accessed - so you'd probably have to keep an extra table around. With a fake group, you only need this table in the body of your .all() function.
Here's a quick sketch of what the fake group might look like:
function yoy_group(group) {
return {
all: function() {
// index all values by date
var bydate = group.all().reduce(function(p, kv) {
p[kv.key.getTime()] = kv.value;
return p;
}, {});
// for any key/value pair which had a value one year earlier,
// produce a new pair with the ratio between this year and last
return group.all().reduce(function(p, kv) {
var date = d3.timeYear.offset(kv.key, -1);
if(bydate[date.getTime()])
p.push({key: kv.key, value: kv.value / bydate[date.getTime()]});
return p;
}, []);
}
};
}
The idea is simple: first index all the values by date. Then when producing the array of key/value pairs, look each one up to see if it had a value one year earlier. If so, push a pair to the result (otherwise drop it).
This should work for any date-keyed group where the dates have been rounded.
Note the use of Array.reduce in a couple of places. This is the spiritual ancestor of crossfilter's group.reduce - it takes a function which has the same signature as the reduce-add function, and an initial value (not a function) and produces a single value. Instead of reacting to changes like the crossfilter one does, it just loops over the array once. It's useful when you want to produce an object from an array, or produce an array of different size from the original.
Also, when indexing an object by a date, I use Date.getTime() to fetch the numeric representation of the date. Otherwise the date coerces to a string representation which may not be exact. Probably for this application it would be okay to skip .getTime() but I'm in the habit of always comparing dates exactly.
Demo fiddle of YOY trade volume in the data set used by the stock example on the main dc.js page.
I've rewritten #Gordon 's code below. All the credit is his for the solution (answered above) and I've just wirtten down my own version (far longer and likely only useful for beginners like me) of the code (much more verbose!) and the explanation (also much more verbose) to replicate my thinking in bridging my near-nothing starting point up to #Gordon 's really clever answer.
yoyGroup = function(group) {
return { all: function() {
// For every key-value pair in the group, iterate across it, indexing it by it's time-value
var valuesByDate = group.all().reduce(function(outputArray, thisKeyValuePair) {
outputArray[thisKeyValuePair.key.getTime()] = thisKeyValuePair.value;
return outputArray;
}, []);
return group.all().reduce(function(newAllArray, thisKeyValuePair) {
var dateLastYear = d3.timeYear.offset(thisKeyValuePair.key, -1);
if (valuesByDate[dateLastYear.getTime()]) {
newAllArray.push({
key: thisKeyValuePair.key,
value: thisKeyValuePair.value / valuesByDate[dateLastYear.getTime()] - 1
});
}
return newAllArray;
}, []); // closing reduce() and a function(...)
}}; // closing the return object & a function
};
¿Why are we overwritting the all() function?
When DC.js goes to create a graph based on a grouping, the only function from Crossfilter it uses is the all() function. So if we want to do something custom to a grouping to affect a DC graph, we only have to overwrite that one function: all().
¿What does the all() function need to return?
A group's all function must return an array of objects and each object must have two properties: key & value.
¿So what exactly are we doing here?
We're starting with an existing group which shows some values over time (Important Assumption: keys are date objects) and then creating a wrapper around it so that we can take advantage of the work that crossfilter has already done to aggregate at a certain level (ex. year, month, etc.).
We start by using reduce to manipulate the array of objects into a more simple array where the keys and values that were in the objects are now directly in the array. We do this to make it easier to look up values by keys.
before / output structure of group.all()
[ {key: k1, value: v1},
{key: k2, value: v2},
{key: k3, value: v3}
]
after
[ k1: v1,
k2: v2,
k3: v3
]
Then we move on to creating the correct all() structure again: an array of objects each of which has a key & value property. We start with the existing group's all() array (once again), but this time we have the advantage of our valuesByDate array which will make it easy to look up other dates.
So we iterate (via reduce) over the original group.all() output and lookup in the array we generated earlier (valuesByDate), if there's an entry from one year ago (valuesByDate[dateLastYear.getTime()]). (We use getTime() so it's simple integers rather than objects we're indexing off of.) If there is an element of the array from one year ago, then we add a key-value object-pair to our soon-to-be-returned array with the current key (date) and for the value we divide the "now" value (thisKeyValuePair.value) by the value 1 year ago: valuesByDate[dateLastYear.getTime()]. Lastly we subtract 1 so that it's (the most traditional definition of) YoY. Ex. This year = 110 and last year = 100 ... YoY = +10% = 110/100 - 1.

Efficient program to keep track of movies and search frequency?

In studying for my exam I came across this question.
A website streams movies to customers’ TVs or other devices. Movies are in one of several genres such as action, drama, mystery, etc. Every movie is in exactly one genre (so that if a movie is an action movie as well as a comedy, it is in a genre called “action-Comedy”). The site has around 10 million customers, and around 25,000 movies, but both are growing rapidly. The site wants to keep track of the most popular movies streamed. You have been hired as the lead engineer to develop a tracking program.
i) Every time a movie is streamed to a customer, its name (e.g. “Harold and Kumar: Escape from Guantanamo Bay”) and genre (“Comedy”) is sent to your program so it can update the data structures it maintains.
(Assume your program can get the current year with a call to an appropriate Java class, in O(1) time.)
ii) Also, every once in a while, customers want to know what were the top k most streamed movies in genre g in year y. (If y is the current year, then accounting is done up to the current date.) For example, what were the top 10 most streamed comedy movies in 2010? Here k = 10, g=”comeday” and y = 2010. This query is sent to your program which should output the top k movie names.
Describe the data structures and algorithms used to implement both requirements. For (i), analyze the big O running time to update the data structures, and for (ii) the big O running time to output the top k streamed movies.
My thought process was to create a hash table, with every new movie added to its respective genre in the hash table in a linked list. As for the second part, my only idea is to keep the linked list sorted but that seems way too expensive. What is a better alternative?
I use a heap to keep track of the top k objects of a class (k fixed). You can find the details of this data structure in any CS text, but basically it's a binary tree in which every node is smaller than either of its children. The main operation, which we will call reheap(node) assumes that both the children of node are heaps, compares node with the smaller of its two children, does the swap if necessary, and recursively calls reheap for the modified child. The class needs to have an overloaded operator< or the equivalent defined to do this.
At any point in time, the heap holds the top k objects with the smallest of these at the top of the heap. When a new object arrives which is bigger than the top of the heap, it replaces that object on the heap, and then
reheap is called. This can also happen at a node other than the top node if an object already on the heap becomes bigger than its smaller child. Another type of update occurs if an object already on the heap becomes smaller than its parent (this probably won't happen in the case you describe). Here it gets swapped with its parent and we then compare recursively against the grandparent, etc.
All of these updates have complexity O(log(k)). If you need to output the heap sorted from the top down, the same structure works well in time
O(k log(k)). (This process is known as heapsort).
Since swapping objects can be expensive, I usually keep the objects in a fixed array somewhere, and implement the heap as an array, A, of pointers, where the children of A[i] are A[2i+1] and A[2i+2].
You could do this in O(1) using one hash table "HT1" to map from (genre, year, movie_title) to an iterator into a linked list of (num_times_streamed, hash table of movie titles). You use the iterator to see if the next element in the list is for one greater streaming count and if so insert your movie title there and remove it from the other table (which if empty can be removed from the list), otherwise if the existing hash table has no other titles then increment the num_times_streamed, otherwise insert a new hash table in the list and add your title. Update the record of the iterator in HT1 as necessary.
Note that as described above the operations in the list use the end-points or an existing iterator to step through by no more than one position as the num_times_streamed value is incremented, so O(1).
To get the top k titles you'll need a hash table HT2 from { genre, year } to each of the linked lists: simply iterate from the end of the list and you'll encounter a hash table with a movie or movies with the highest streaming count, then the next highest and so on. If the year's just changed, you may not find k entries, handle that however you like. If when looking up a movie title it's found not to exist in HT1, you'd add a new list for that genre and the current year to HT2.
More visually, using { } around hash tables (whether mappings or sets), [ ] around linked lists, and ( ) around grouped struct/tuple data:
HT2 = { "comedy 2015": [ (1, { "title1", "title2" }),
(2, { "title3" }), <--------\
(4, { "title4" }) ], |
"drama 2012": [ (1, { "title5" }), |
(3, { "title6" }) ], |
... | .
}; | .
| .
HT1 = { "title3", -----------------------------------/ |
"title2", ---------------------------------------/
...
};

Finding the lowest unused unique id in a list

Say there's a list. Each item in the list has a unique id.
List [5, 2, 4, 3, 1]
When I remove an item from this list, the unique id from the item goes with it.
List [5, 2, 3, 1]
Now say I want to add another item to the list, and give it the least lowest unique id.
What's the easiest way to get the lowest unique id when adding a new item to the list?
Here's the restriction though: I'd prefer it if I didn't reassign the unique id of another item when deleting an item.
I realise it would be easy to find the unique id if I reassigned unique id 5 to unique id 4 when I deleted 4. Then I could get the length of the list (5) and creating the new item with the unique id with that number.
So is there another way, that doesn't involve iterating through the entire list?
EDIT:
Language is java, but I suppose I'm looking for a generic algorithm.
An easy fast way is to just put your deleted ids in a priority queue, and just pick the next id from there when you insert new ones (or use size() + 1 of the first list as id when the queue is empty). This would however require another list.
You could maintain a list of available ID's.
Declare a boolean array (pseudo code):
boolean register[3];
register[0] = false;
register[1] = false;
register[2] = false;
When you add an element, loop from the bottom of the register until a false value is found. Set the false value to true, assign that index as the unique identifier.
removeObject(index)
{
register[index] = false;
}
getsetLowestIndex()
{
for(i=0; i<register.size;i++)
{
if(register[i]==false)
{
register[i] = true;
return i;
}
}
// Array is full, increment register size
register.size = register.size + 1;
register[register.size] = true;
return register.size;
}
When you remove an element, simply set the index to false.
You can optimise this for larger lists by having continuality markers so you don't need to loop the entire thing.
This would work best for your example where the indexes are in no particular order, so you skip the need to sort them first.
Its equivalent to a search, just this time you search for a missing number. If your ID's are sorted integers, you can start going from bottom to top checking if the space between two ID's is 1.
If you know how many items in the list and its sorted you can implement a binary search.
I don't think you can do this without iterating through the list.
When you say
'Now say I want to add another item to
the list, and give it the least
highest unique id. '
I assume you mean you want to assign the lowest available ID that has not been used elsewhere.
You can do this:
private int GetLowestFreeID(List list){
for (int idx = 0; idx < list.Length; ++i){
if ( list[idx] == idx ) continue;
else return idx;
}
}
this returns the lowest free index.
This assumes your list is sorted, and is in C# but you get the idea.
The data structure that would be used to do this is a Priority Binary Heap that only allow unique values.
How about keeping the list sorted. and than you can remove it from one end easily.

Resources