我想要一个逻辑,而不是那么多 if 语句,我可以用一个语句或优化的方式来完成
instead of so many if statements I want a logic where I can do it with one statement or optimized way
我有一个结构向量 vector<S> sData
,我的结构包含 5 个元素(姓名、年龄、技术、项目、语言)
用户可以输入名称,它应该输出与该名称相同的结构以及其他元素。
我的问题是用户只能输入其中两个,它应该只检查那些用户可以输入年龄和语言,它应该输出具有相同年龄和语言的人的列表。如果你想象你可以写这么多 if 语句,那么它会给出正确的输出,因为你有 5 个元素,
并且用户可以选择其中的 4 个中的 5 个,他可以随机输入其中的 3 个或 4 个,我的程序应该理解这个逻辑。
在我的代码中,我使用 Qt 小部件应用程序编写。当用户没有输入任何字符串(name, techs, projects, rate)时,默认值为NULL,年龄为-1.
struct S
{
QString name;
int age;
QString techs;
QString projects;
QString rate;
};
QVector<S> sData;
QVector<int> indexData;
//this is how i did for the name
indexData.clear();
if(searchName!=NULL)//i don't want to write this if for name and age ||
// name and tech ... then age and tech etc.
{
for(int i=0;i<sData.count();++i)
{
if(searchName==sData[i].name)
{
indexData.push_back(i);
}
}
}
这有帮助吗?
struct S
{
QString name;
int age;
QString techs;
QString projects;
QString rate;
};
QVector<S> sData;
QVector<int> indexData;
int main() {
searchName = ...;
searchAge = ...;
searchTechs = ...;
...
auto it = std::find_if(std::begin(sData), std::end(sData),
[&searchName, &searchAge, &searchTecs, ...](const S& s)
{
bool eq = true;
if (searchName)
eq &= (searchName == s.name);
if (searchAge)
eq &= (searchAge == s.age);
if (searchTechs)
eq &= (searchTechs == s.techs);
....
return eq;
}
if (it == std::end(sData))
std::terminate(); //element not found
// *it is the desired element
}
或者如果你想找到匹配的每个元素
int i = 0;
for (const S& s : sData) {
bool eq = true;
if (searchName)
eq &= (searchName == s.name);
if (searchAge)
eq &= (searchAge == s.age);
if (searchTechs)
eq &= (searchTechs == s.techs);
....
if (eq)
indexData.push_back(i);
++i;
}
我建议进行一些代码重构。让我们考虑添加一个辅助结构 SearchS,它包含您要查找的所有参数(和比较运算符):
struct S {
QString name;
int age = -1;
QString techs;
QString projects;
QString rate;
};
struct SearchS {
std::optional<QString> name;
std::optional<int> age;
std::optional<QString> techs;
std::optional<QString> projects;
std::optional<QString> rate;
static bool string_match(const QString& s, const std::optional<QString>& search_s) {
return !search_s || *search_s == s;
}
bool operator==(const S& s) const noexcept {
return string_match(s.name, name) &&
string_match(s.techs, techs) &&
string_match(s.projects, projects) &&
string_match(s.rate, rate) &&
(!age || *age == s.age);
}
};
这允许您迭代数据向量和过滤结果。
我认为最干净的方法是使用 ranges-v3:
std::vector<S> sData;
SearchS target;
target.name = "John";
target.age = 28;
// ... other params if needed ...
auto filtered_items = data | ranges::views::filter([&target](const auto& item) {
return target == item;
});
您可以在此处应用其他过滤器...或迭代过滤结果:
for(auto&& item : filtered_items) {
// ... add your code here ...
}
我有一个结构向量 vector<S> sData
,我的结构包含 5 个元素(姓名、年龄、技术、项目、语言)
用户可以输入名称,它应该输出与该名称相同的结构以及其他元素。
我的问题是用户只能输入其中两个,它应该只检查那些用户可以输入年龄和语言,它应该输出具有相同年龄和语言的人的列表。如果你想象你可以写这么多 if 语句,那么它会给出正确的输出,因为你有 5 个元素, 并且用户可以选择其中的 4 个中的 5 个,他可以随机输入其中的 3 个或 4 个,我的程序应该理解这个逻辑。
在我的代码中,我使用 Qt 小部件应用程序编写。当用户没有输入任何字符串(name, techs, projects, rate)时,默认值为NULL,年龄为-1.
struct S
{
QString name;
int age;
QString techs;
QString projects;
QString rate;
};
QVector<S> sData;
QVector<int> indexData;
//this is how i did for the name
indexData.clear();
if(searchName!=NULL)//i don't want to write this if for name and age ||
// name and tech ... then age and tech etc.
{
for(int i=0;i<sData.count();++i)
{
if(searchName==sData[i].name)
{
indexData.push_back(i);
}
}
}
这有帮助吗?
struct S
{
QString name;
int age;
QString techs;
QString projects;
QString rate;
};
QVector<S> sData;
QVector<int> indexData;
int main() {
searchName = ...;
searchAge = ...;
searchTechs = ...;
...
auto it = std::find_if(std::begin(sData), std::end(sData),
[&searchName, &searchAge, &searchTecs, ...](const S& s)
{
bool eq = true;
if (searchName)
eq &= (searchName == s.name);
if (searchAge)
eq &= (searchAge == s.age);
if (searchTechs)
eq &= (searchTechs == s.techs);
....
return eq;
}
if (it == std::end(sData))
std::terminate(); //element not found
// *it is the desired element
}
或者如果你想找到匹配的每个元素
int i = 0;
for (const S& s : sData) {
bool eq = true;
if (searchName)
eq &= (searchName == s.name);
if (searchAge)
eq &= (searchAge == s.age);
if (searchTechs)
eq &= (searchTechs == s.techs);
....
if (eq)
indexData.push_back(i);
++i;
}
我建议进行一些代码重构。让我们考虑添加一个辅助结构 SearchS,它包含您要查找的所有参数(和比较运算符):
struct S {
QString name;
int age = -1;
QString techs;
QString projects;
QString rate;
};
struct SearchS {
std::optional<QString> name;
std::optional<int> age;
std::optional<QString> techs;
std::optional<QString> projects;
std::optional<QString> rate;
static bool string_match(const QString& s, const std::optional<QString>& search_s) {
return !search_s || *search_s == s;
}
bool operator==(const S& s) const noexcept {
return string_match(s.name, name) &&
string_match(s.techs, techs) &&
string_match(s.projects, projects) &&
string_match(s.rate, rate) &&
(!age || *age == s.age);
}
};
这允许您迭代数据向量和过滤结果。 我认为最干净的方法是使用 ranges-v3:
std::vector<S> sData;
SearchS target;
target.name = "John";
target.age = 28;
// ... other params if needed ...
auto filtered_items = data | ranges::views::filter([&target](const auto& item) {
return target == item;
});
您可以在此处应用其他过滤器...或迭代过滤结果:
for(auto&& item : filtered_items) {
// ... add your code here ...
}