106

I am trying to get the index of an element in a vector of strings, to use it as an index in another vector of int type, is this possible ?

Example:

vector <string> Names;
vector <int> Numbers;

 ... 
// condition to check whether the name exists or not
if((find(Names.begin(), Names.end(), old_name_)) != Names.end())  
    {   // if yes
        cout <<"Enter the new name."<< endl;
        cin >> name;
        replace(Names.begin(), Names.end(), old_name_, name);
    }

Now I want to get the position of old_name in the Names vector, to use it in accessing certain element in Numbers vector. So that I can say:

Numbers[position] = 3 ; // or whatever value assigned here.

I tried using:

vector <string> :: const_iterator pos;
pos = (find(Names.begin(), Names.end(), old_name_))
Numbers[pos] = 3;

but obviously this doesn't work since pos is of type string !

Grzegorz Krukowski
  • 14,128
  • 5
  • 41
  • 61
Nour
  • 1,939
  • 3
  • 14
  • 17

3 Answers3

169

To get a position of an element in a vector knowing an iterator pointing to the element, simply subtract v.begin() from the iterator:

ptrdiff_t pos = find(Names.begin(), Names.end(), old_name_) - Names.begin();

Now you need to check pos against Names.size() to see if it is out of bounds or not:

if(pos >= Names.size()) {
    //old_name_ not found
}

vector iterators behave in ways similar to array pointers; most of what you know about pointer arithmetic can be applied to vector iterators as well.

Starting with C++11 you can use std::distance in place of subtraction for both iterators and pointers:

ptrdiff_t pos = distance(Names.begin(), find(Names.begin(), Names.end(), old_name_));
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • Sorry, I can't see @Bob__ 's comments, maybe deleted? I'm wondering why `ptrdiff_t` is better than `size_t` since `ptrdiff_t ` would raise a warning of comparison between signed and unsigned integer – Hiraku Oct 17 '17 at 05:43
  • 3
    @Hiraku He did delete his comment. He suggested using `ptrdiff_t` because it lets you store the distance between any pair of iterators into the same container, even in situations when the result is negative. If we use `size_t` we must be careful not to subtract a larger iterator from a smaller iterator. – Sergey Kalinichenko Oct 17 '17 at 10:49
  • 2
    To be more precise, you should add "#include " (for using std::find). Author of question omitted this "include" too. – Grag2015 Oct 19 '18 at 21:19
95

If you want an index, you can use std::find in combination with std::distance.

auto it = std::find(Names.begin(), Names.end(), old_name_);
if (it == Names.end())
{
  // name not in vector
} else
{
  auto index = std::distance(Names.begin(), it);
}
juanchopanza
  • 210,243
  • 27
  • 363
  • 452
-3

I am a beginner so here is a beginners answer. The if in the for loop gives i which can then be used however needed such as Numbers[i] in another vector. Most is fluff for examples sake, the for/if really says it all.

int main(){
vector<string>names{"Sara", "Harold", "Frank", "Taylor", "Sasha", "Seymore"};
string req_name;
cout<<"Enter search name: "<<'\n';
cin>>req_name;
    for(int i=0; i<=names.size()-1; ++i) {
        if(names[i]==req_name){
            cout<<"The index number for "<<req_name<<" is "<<i<<'\n';
            return 0;
        }
        else if(names[i]!=req_name && i==names.size()-1) {
            cout<<"That name is not an element in this vector"<<'\n';
        } else {
            continue;
        }
    }
javer
  • 1