Datastorage unique and ordered
-
I am looking for a storage type which would allow me to hold a sequence of values, but would avoid duplicate values.
I was originally looking atBaseArray
but when appending a new value I would like to avoid iterating over all entries to find out if this new value is already present.
AnHashMap
doesn't preserve the order of items being inserted (as far as I know).
As such I was more thinking about a custom class containing:- a
BaseArray
to hold the values in the order they are appended. - an
HashMap
to hold the values (as key) in order to perform an easyFind
, knowing if the value should be appended or not.
But having the values stored twice this would mean this custom class takes up twice the memory.
Since I intend to share implementation between R20 and pre-R20 I cannot rely on the newmaxon::Data
ormaxon::DataDictionnary
.Anyone having a better idea than the BaseArray-HashMap combination?
The storage type should be able to handle any type of data, from Int32, Float, Strings, custom class instances, ...Example with Int32:
input = 0, 1, 2, 0, 3, 1, 5, 4
The data storage should hold:
0, 1, 2, 3, 5, 4 - a
-
hello,
looks like you need a HashSet
I first thought you wanted a sorted array with unique value.
I would than go with a sorted array and Unique witch give you a iterator that you can use in the Erase Function of the Sorted Array
Cheers
Manuel -
@m_magalhaes
Hi,
HashSet
seems indeed what I need. From the name I assumed its functionality was similar to std::set which is not what I wanted. But I have tested outHashSet
in R20 and it does provide the result I was looking for.
Unfortunately, I could not get to compile the test in R19.
TheInsert()
function in R20 was to be replaced by anAdd()
, no problems there.
But iterating (using iterator or range based loop) does not compile, as it seems the iterators are derived privately from the base classHashMap
error C2247: 'maxon::HashMap<V,maxon::EmptyClass,HASH,maxon::HashMapKeyValuePair,ALLOCATOR>::begin' not accessible because 'maxon::HashSet<Int32,maxon::DefaultHash,maxon::DefaultAllocator>' uses 'private' to inherit from 'maxon::HashMap<V,maxon::EmptyClass,HASH,maxon::HashMapKeyValuePair,ALLOCATOR>' ```.
-
hello,
on R19 you can use this code to iterate through your array. (or did i missed something here)
The rangeLoop is not possible yea.for (auto it = myarray.Begin(); it != myarray.End(); it++) { GePrint("value is " + String::IntToString(*it)); }
Cheers
Manuel -
@m_magalhaes
Thanks for reminding me of the "auto" ...Yesterday I had tried using the iterator, but got compiler error, then I tried the range-based loop, again hitting a compiler error.
I don't quite get the difference between following two implementations
maxon::HashSet<Int32>::Iterator it; for (it = hashset.Begin(); it != hashset.End(); ++it) GePrint("HashSet value " + String::IntToString(*it));
for (auto it = hashset.Begin(); it != hashset.End(); ++it) GePrint("HashSet value " + String::IntToString(*it));
The first implementation (which I tried using ... not thinking about using "auto") gives me following errors:
error C2512: 'maxon::HashSet<Int32,maxon::DefaultHash,maxon::DefaultAllocator>::Iterator': no appropriate default constructor available error C2248: 'maxon::HashSet<Int32,maxon::DefaultHash,maxon::DefaultAllocator>::Iterator::operator =': cannot access private member declared in class 'maxon::HashSet<Int32,maxon::DefaultHash,maxon::DefaultAllocator>::Iterator'
I am confused that using "auto" does work.
Especially that when hovering over "auto" in Visual Studio does show a popup, containing "class maxon::HashSet<Int32>::Iterator" ... exactly what the first implementation does. -
hello,
no appropriate default constructor available
The difference is the iterator initialization.
// same as // maxon::HashSet<maxon::Int32>::Iterator it(myarray.Begin()); maxon::HashSet<maxon::Int32>::Iterator it = myarray.Begin(); for (it; it != myarray.End(); it++) { GePrint("without auto value is " + String::IntToString(*it)); }
or prefered (and that's what the auto is doing)
for (maxon::HashSet<maxon::Int32>::Iterator it = myarray.Begin(); it != myarray.End(); it++) { GePrint("without auto value is " + String::IntToString(*it)); }
I will ask the other what they think about it but it's more a c++/ compiler question than a SDK question.
Cheers
Manuel -
@m_magalhaes
I agree that the last few replies to this thread are C++ and not SDK related.
The main topic lead to theHashSet
, and for completeness of future reference I thought to mention the compiling issues.
I didn't know about the difference being the iterator initialization. To me it all looked the same.Just for completeness, I never really realized the following two implementations had a complete different internal behaviour:
// does compile maxon::HashSet<Int32>::Iterator it = hashset.Begin(); // does not compile maxon::HashSet<Int32>::Iterator it; it = hashset.Begin();
I will set the topic as solved, since
HashSet
is the way to go, and I learned something new about iterator initialization in the process. -
hello,
It's not related to Iterator.
This simple example also complain about the default constructor.#include <iostream> class MYINT { public: MYINT(int inInt) { _myint = inInt; }; private: int _myint; }; int main() { MYINT myint; system("pause"); return 0; }
It should say 'hey i don't have any constructor with no parameters".
But if you give him something to initialize with it understand.
MYINT myint = MYINT(10); MYINT myOtherInt = 10; MYINT myThirdInt(10);
all this will end with _myint = 10;
Cheers
Manuel