Search code examples
c++vectorunordered-set

Retrieving data from vectors and unordered_sets


I've started to put data into vectors and unordered_sets. I've worked out fairly easily how to put the data in, and I know how to get the data out if I need to unload all the data, for example:

for (auto i : vehicles)
    MakeSpawnInfoVehicle(i.AddedInformation);

However, I've reached a point where I want just one element of information from either the unordered_sets or vectors such as what ever the 10th entry is in the vector or the unordered_set.

If someone could provide a basic example of both, I'm sure I'll understand it.


Solution

  • In situations like this, you can consult a good reference.

    std::vector provides operator[] with constant-time performance:

    auto tenth_element = vehicle_vector[9];
    

    std::unordered_set is optimised for element-based lookup (that is, testing whether an element is present or not). It is rare you would need the 10th element (especially since the set is, by definition, unordered), but if you do, you take an iterator, increment it and dereference it:

    auto tenth_element = *std::next(vehicle_set.begin(), 9);
    

    In general, you access the elements of a container either through the container's member functions (such as the vector's operator [] above), or through an iterator.

    An iterator is a generalisation of a pointer - it's some unspecified type which points to an element in the container. You can then work with iterators using their member functions like operator ++ or free functions like std::next(). Random-access iterators also support []. To get the element to which the iterator "points," dereference the iterator like *it or it->whatever.

    You obtain an iterator to the beginning of the container using begin() and an iterator to one past the last element using end(). Containers can also provide other member functions to get an iterator to an element - such as vehicle_set.find(aVehicle), which returns an iterator to aVehicle if it's present in the set, or the end() iterator if it's not.

    Which member functions a container offers depends on which container it is and in particular how efficient the operations are. std::vector doesn't proivde find(), because it would be no better than std::find() - there is no structure in std::vector for fast lookup. std::unordered_set does provide find(), but doesn't have operator [], because its iterators are not random-access: accessing the nth element of an unordered set requires time proportional to n.