How to retrieve nth element from the sorted keys of sorted TreeMap? - html-lists

I am using TreeMap to as I want to store sorted keys. I have also passed the comparator to sort the order. Now, I want to retrieve the 2nd key form the map. How do I go about doing it. The TreeMap is as given below :
private TreeMap<Coupon, LineItem> couponVsDiscountLine = new TreeMap<>((c1, c2) -> c1.weight().compareTo(c2.weight()));
Getting the sorted keys from TreeMap :
TreeSet<Coupon> coupons = (TreeSet<Coupon>) couponVsDiscountLine.keySet();
There is no method in TreeSet to get(index) as the elements in TreeSet are not indexed.
Other question, which Set does keySet() method of TreeMap return? How does TreeMap store the keys internally?
I read in some post that the TreeMap or TreeSet does not maintain the order if any modifications is done on that. Does it mean that retrieval of element may not give the elements in the order specified in the comparator?

Related

Dual-keyed map without additional data, is it possible?

Let's assume that we have a huge map where each element need to be accessed by 2 different keys, K1 and K2. We have both K1 and K2 when we add data to the tree, but we need to retrieve data using either K1 or K2. This means both K1 and K2=ignored and K1=ignored and K2 while retrieving data refer to the data defined by K1 and K2. Is it possible to do this with a correct comparison method, without duplicating data or using secondary map for showing relationship between K1 and K2 (because these 2 methods are obvious but both need to secondary data)? What about hash maps? Because hash maps need both comparison and hash methods.
You can solve this the following way.
Lets say you maintain a single Map <Key,Value> map to store your info.
Now, you when you want to store 2 keys K1 and K2 to a value. Store it in a hierarchial form with a parent-child relationship between K1 and K2.
For, example, the map structure would look like this.
K1 - Value
K2 - <child_of_identifier>K1
So, whenver you want to query using K1 or K2, you can do the following:
if(map.exists(key)){
if(map.get(key).startsWith("<child_of_identifier>"){
// Parse parent key value
return map.get(parent_key)
}else{
return map.get(key);
}
}
About the solution:
Does not duplicate data
Does not have another auxillary map
Two lookups for child keys
Flat storage of keys instead of merging 2 keys.

Simpler alternative to simultaneously Sort and Filter by column in Google Spreadsheets

I have a spreadsheet (here's a copy) with the following (headered) columns:
A: Indices for a list of groceries;
B: Names for the groceries to be indexed by column A;
C: Check column with "x" for inactive items in column B, empty otherwise;
D: Sorting indices that I want to apply to column B;
Currently, I am getting the sorted AND filtered result with this formula:
=SORT(FILTER(B2:B; C2:C = ""); FILTER(D2:D; C2:C = ""); TRUE)
The problem is that I need to apply the filter two times: one for the items and one for the indices, otherwise I get a mismatch between elements for the Sort function.
I feel that this doesn't scale well since it creates duplication.
Is there a way to get the same results with a simpler formula or another arrangement of columns?
=SORT(FILTER({Itens!B2:B\Itens!G2:G}; Itens!D2:D=""))
=SORT(FILTER({Itens!B2:B\Itens!G2:G}; Itens!D2:D="");2;1)
or maybe: =SORT(FILTER(Itens!B2:B; Itens!D2:D="");2;1)

Hashing methodology for collection of strings and integer ranges

I have a data, for example per the following:
I need to match the content with the input provided for the Content & Range fields to return the matching rows. As you can see the Content field is a collection of strings & the Range field is a range between two numbers. I am looking at hashing the data, to be used for matching with the hashed input. Was thinking about Iterating through the collection of individual strings hashcode & storing it for the Content field. For the Range field I was looking at using interval trees. But then the challenge is when i hash the Content input & Range input how will i find if it that hashcode is present in the hashcode generated for the collection of strings in the Content fields & the same for the Range fields.
Please do let me know if there are any other alternate ways in which this can be achieved. Thanks.
There is a simple solution to your problem: Inverted Index.
For each item in content, create the inverted index that maps 'Content' to 'RowID', i.e. create another table of 2 columns viz. Content(string), RowIDs(comma separated strings).
For your first row, add the entries {Azd, 1}, {Zax, 1}, {Gfd, 1}..., {Mni, 1} in that table. For the second row, add entries for new Content strings. For the Content string already present in the first row ('Gfd', for example), just append the new row id to the entry you created for first row. So, Gfd's row will look like {Gfd, 1,2}.
When done processing, you will have the table that will have 'Content' strings mapped to all the rows in which this content string is present.
Do the same inverted indexing for mapping 'Range' to 'RowID' and create another table of Range(int), RowIDs(comma seperated strings).
Now, you will have a table whose rows will tell which range is present in which row ids.
Finally, for each query that you have to process, get the corresponding Content and Range row from the inverted index tables and do an intersection of those comma seperated list. You will get your answer.

d3: difference between sort and ascending

I wanted to know the difference between sort function and ascending function in d3.
I am looking for a way to rearrange the data in my table in ascending order of the column selected.
Thanks.
Array.sort() will sort the values alphabetically in ascending order. Array.sort(d3.ascending) will sort the values naturally in ascending order. The difference can be seen when you are sorting a list of numbers.
var a = [3,26,1,7];
console.log(a.sort());
// prints [1,26,3,7]
console.log(a.sort(d3.ascending));
// prints [1,3,7,26]
For additional information on how sort works, see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort.

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