Picking array items by name
One could think I''ve been programming long enough to know an answer of this but...
Anyway I''ve got an array like this:
MyType MyArray[10];
And then I pick one of the items:
MyArray[3].DoSomething(SomeArgument);
Now, for the simplicity of things, I want to be able to give each item in the array a name and then use that name as identifier.
Something like this:
MyType MyArray[10];
MyArray[0].Name = "Item1"
MyArray[1].Name = "AnotherItem"
MyArray[2].Name = "AThidItem"
..and so on..
MyArray[AnotherItem].DoSomething(SomeArgument);
The point is, that I want to be able to assign a name dynamicly. I know it would have been easy using defines or an enum.
Suggestions?
-Luctus
Your assigning names as strings, so you would want to be able to get the object based on that (string name), no?
I don''t think you can do this w/ a normal array.. this is not perl (in which I''m pretty sure you can).
You''ll have to create an class that mimics an array, and probably create it as a template. And allow the passing of a string as an argument to operator []. Then use the name to search for the object in the array.. Just a suggestion.
Otherwise, you could do enums, but I don''t think you can create new enum values at run time.
Sorry if this didn''t help.
I don''t think you can do this w/ a normal array.. this is not perl (in which I''m pretty sure you can).
You''ll have to create an class that mimics an array, and probably create it as a template. And allow the passing of a string as an argument to operator []. Then use the name to search for the object in the array.. Just a suggestion.
Otherwise, you could do enums, but I don''t think you can create new enum values at run time.
Sorry if this didn''t help.
std::map is what you''re looking for.
This is all from memory so i could be wrong, but it should work.
#include <map>#include <string>using namespace std;map<string, MyType> MyMap;// to insert a memberMyType SomeType;MyMap.insert( make_pair( "Item1", SomeType ) );// to look it up the easy wayMyType AnotherType = MyMap["Item1"];// for a faster looking up (i think)map<string, MyType>::iterator it = MyMap.find("Item1");if (it == MyMap.end()) { // "Item1" wasnt found} else { // else "Item1" was found MyType YetAnotherType = (*it).second;}
This is all from memory so i could be wrong, but it should work.
The closest thing to what you want is a map or other associative data structure. What a map does is that it keeps sorted pairs of keys and values (the STL std::map allows only one value per key; std::multimap allows multiple values per key):
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! | Asking Smart Questions | Internet Acronyms ]
Thanks to Kylotan for the idea!
#include <map>std::map< std::string, long > Items;...Items[ "You" ] = 0;Items[ "Me" ] = 1;...cout << ( Items[ "Him" ] = 2 ) << endl;
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! | Asking Smart Questions | Internet Acronyms ]
Thanks to Kylotan for the idea!
I see three ways to solve your problem:
- The first easy way would be to make a fuction that searches through your class array:
MyType* GetObject(char* Object_Name)
...i=0
...while (i < max_number of objects)
......if (strcomp(MyArray.Name, Object_Name) == 0)
.........return MyArray<br>……i++<br><br>It is not reusable. You can create a class manager that holds a pointer to the array and that implements different methods to search or modify your array. A little better design wise, but you are then closer to …<br><br>- The second way is to create a vector of your class and use the find algorithm (STL)<br>If you are not proficient with vectors and algorithms, look at the following links: <br>www.sgi.com/tech/stl/<br>www.devx.com/upload/free/features/vcdj/2000/04apr00/bw0400/bw0400.asp<br><br>- The third way is to create your own templated array manager. See the following link to get you started more generally on templates:<br>http://www.infosys.tuwien.ac.at/Research/Component/tutorial/prwmain.htm<br><br>Hope that helps.<br><br>Ghostly yours,<br>Red. </i>
- The first easy way would be to make a fuction that searches through your class array:
MyType* GetObject(char* Object_Name)
...i=0
...while (i < max_number of objects)
......if (strcomp(MyArray.Name, Object_Name) == 0)
.........return MyArray<br>……i++<br><br>It is not reusable. You can create a class manager that holds a pointer to the array and that implements different methods to search or modify your array. A little better design wise, but you are then closer to …<br><br>- The second way is to create a vector of your class and use the find algorithm (STL)<br>If you are not proficient with vectors and algorithms, look at the following links: <br>www.sgi.com/tech/stl/<br>www.devx.com/upload/free/features/vcdj/2000/04apr00/bw0400/bw0400.asp<br><br>- The third way is to create your own templated array manager. See the following link to get you started more generally on templates:<br>http://www.infosys.tuwien.ac.at/Research/Component/tutorial/prwmain.htm<br><br>Hope that helps.<br><br>Ghostly yours,<br>Red. </i>
Red:
[ source ]
[ /source ]
(without spaces) will put your code in nice little source blocks. Just FYI. Also takes care of problem of italicizing your entire post if you use ''i'' in a subscript. Good posts, btw. Good to have you around.
[ source ]
[ /source ]
(without spaces) will put your code in nice little source blocks. Just FYI. Also takes care of problem of italicizing your entire post if you use ''i'' in a subscript. Good posts, btw. Good to have you around.
Just to extend what Red Ghost already said, you could make yourself a simple array class and overload operator[] to accept string literals instead of a numeric index. You could do something like this:
What can I say? I felt like coding. With this code—assuming that it''s correct—you should be able to do std::vector-like stuff, but using a string literal for access.
template<class T>class array{ private: template<class T> struct node { T data; const char* name; }; public: array(unsigned int initial_capacity = 0): m_capacity(initial_capacity), m_size(0), m_data(0) {reserve(initial_capacity);} ~array() {clear();} unsigned int size() const {return m_size;} unsigned int capacity() const {return m_capacity;} void reserve(unsigned int new_capacity) { if(new_capacity <= m_capacity) return; node<T>* temp = new node<T>[new_capacity]; for(unsigned int = 0; i < m_capacity; ++i) temp[i] = m_data[i]; delete m_data; m_data = temp; m_capacity = new_capacity; } void add(const char* name, const T& data) { reserve(++m_size); m_data[m_size+ 1] = data; } void clear() { delete[] m_data; m_size = m_capacity = 0; } T& operator[](const char* name) { for(unsigned int i = 0; i < m_size; ++i) if(strcmp(m_data[i].name, name) == 0) return m_data[i].data; // to keep the compiler happy (we should throw // an exception before we get here) return m_data[0].data; } const T& operator[](const char* name) const { for(unsigned int i = 0; i < m_size; ++i) if(strcmp(m_data[i].name, name) == 0) return m_data[i].data; // to keep the compiler happy (we should throw // an exception before we get here) return m_data[0].data; } private: node<T>* m_data; unsigned int m_capacity; unsigned int m_size;};
What can I say? I felt like coding. With this code—assuming that it''s correct—you should be able to do std::vector-like stuff, but using a string literal for access.
array<int> stuff(4); // reserve enough space for 4 items, though // both add and reserve can increase thisstuff.add("Peach", 3);stuff.add("Banana", 1);stuff.add("Orange", 5);stuff.add("Apple", 6);stuff["Orange"] = 6;if(stuff["Apple"] == stuff["Orange"]) stuff["Peach"] = 2;
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement