user2792781
user2792781

Reputation: 29

Check if input is equal to a value present in an array?

I want to check if the input is equal to any of the options in an array. How do I do it? Can I do it without using a lot of || operators?

    //check if any input in herp[] was entered
    string input;
    string herp[2] = {"Merp", "Derp"}
    cin >> input;
    if (input == "connect "+herp[0]||"connect "+herp[1]) {
        cout << "poopie" << endl;
    }

Upvotes: 2

Views: 5200

Answers (6)

Shane Hsu
Shane Hsu

Reputation: 8357

I came up with a couple approaches,

First, with a custom function,

template<typename ValueType, typename ForwardIterator>
bool is_in(ValueType value, ForwardIterator begin, ForwardIterator end) {
    while (begin != end) {
        if (value == *(begin ++)) {
            return true;
        }
    }
    return false;
}

template<typename ValueType, typename ForwardIterator>
bool is_in(ValueType value, ForwardIterator begin, ForwardIterator end) {
    if (begin == end) return false;
    return value == *(begin ++) || is_in(value, begin, end);
}

They do basically the same thing, one that does it recursively, another iteratively.

Adding to jrok's answer, this also does the trick, but without lambda.

std::any_of(predicates.begin(), predicates.end(), std::bind(std::equal_to<std::string>(), "dance", std::placeholders::_1));

By using std::bind we can avoid using an additional lambda.

The last assumes that you have just a few constant predicates,

template<typename Comparable>
bool is_any(Comparable value) {
    return false;
}

template<typename ValueType, typename Comparable, typename... Comparables>
bool is_any(ValueType value, Comparable predicate, Comparables... predicates) {
    return value == predicate || is_any(value, predicates...);
}

You can just use it like this,

is_any("dance", "apple", "banana", "cat"); // false

Upvotes: 0

TommasoF
TommasoF

Reputation: 825

Solution:

string input;
const int len = 2;
string herp[len] = {"Merp", "Derp"}
cin >> input;

for( int i = 0 ; i < len ; i++){
   if(input == herp [i])
      cout << "poopie" << endl;

Upvotes: 1

UpAndAdam
UpAndAdam

Reputation: 5467

To highlight why jroc's (or Zac's) answer is so powerful, here's how you can use reuse to handle the append, or potentially suffix... Note this is significantly more efficient O(1) than creating new strings each time by concatenation which render your entire solution down at O(N) and completely suck.

//this function can either be jroc's first or second variant implementation
bool jroc_find(const std::string& input, std::vector<string> array) { .... };

...
int main(...) {
    ...
    string input, search;
    cin >> input;
    string prefix("connect _");
    if (input.substr(0,prefix.length) != prefix )
        return -1; //not found
    else
        search = input.subst(prefix.length, input.length - prefix.length);
    return jroc_find(search, herp);
    ...
}

Upvotes: 0

user425495
user425495

Reputation:

Consider replacing your data structure for herp; use std::set if you need the strings to be ordered or std::unordered_set otherwise. Then it's a simple check to see if herp.find(input) != herp.end(). These data structures will provide you better complexity guarantees for the find operation (logarithmic and constant amortized for std::set and std::unordered_set respectively) over using std::find on an array (linear). However, these details are less important if you don't expect the size of herp to ever grow beyond 2.

Upvotes: 3

jrok
jrok

Reputation: 55395

Use std::find:

#include <algorithm>

if (std::find(std::begin(herp), std::end(herp), input) != std::end(herp)) {
    cout << "found it!";
}

Also, in C++11, std::any_of has been added. You'll need a predicate function, here in a form of a lambda:

if (std::any_of(std::begin(herp), std::end(herp),
    [&input](const std::string& str) { return str == input; })) {
    cout << "found it!";
}

I'd also suggest that you don't use raw arrays, but std::vector or std::array instead. It might not matter if it's in the same function, but when you pass C-arrays around, they decay to pointers and then things quickly get messy.

Upvotes: 12

Zac Howland
Zac Howland

Reputation: 15872

If you don't need to append anything:

std::string* p = std::find(std::begin(herp), std::end(herp), input);
if (p != std::end(herp))
{
    std::cout << *p << std::endl;
}
else
{
    std::cout << "Not found" << std::endl;
}

If you do need to append something, there are a lot of different options. One of them:

std::vector<std::string> herps;

std::string myAppend(const std::string& a)
{
    return "connect " + a;
}

std::transform(std::begin(herp), std::end(herp), std::back_inserter(herps), myAppend);
std::string* p = std::find(herps.begin(), herps.end(), input);
if (p != herps.end())
{
    std::cout << *p << std::endl;
}
else
{
    std::cout << "Not found" << std::endl;
}

Upvotes: 2

Related Questions