QStringList
是 Qt 框架中的一个类,用于存储一组字符串。它是一个动态数组,可以根据需要自动调整大小,并提供了一些方便的方法来操作字符串列表。
这里我们主要是处理的是,包含有一定规律的QString,或者有一定规律的QStringList;
例如,我有以下几种命名格式,"aaa"、"1_bbb"、"2_ccc_d",简化一下就是"名称"、"数字_名称_其他信息"。
我们不妨再来提一个需求,有若干QString,全部都乱序放在QStringList中,每个QString用以上某中命名格式来命名,我需要将这些元素进行排序,以"aaa"格式的排在前面,以"1_bbb"、"2_ccc_d"格式的根据数字大小,顺序排序,并切割为"bbb","ccc" 这种形式,若数字相同,则按照索引大小顺序排列。
例如,输入一个QStringList,其中的元素有"张主任","1_李四","3_王五_班主任","5_刘星_语文老师","5_刘望_数学老师","4_林木","1_李子木","王主任";
切割并排序后,输出为:"张主任","王主任","李四","李子木","王五","林木","刘星","刘望"
以下是使用到的主要代码:
// 假设我们已经知道了需要的转换的名称列表,可以是成员变量
QStringList sort_name_list_; // 用于传入到SetNameList()中,以及在RestoreName()中使用
// 过滤名称列表,传入的值是 sort_name_list_
QStringList SetNameList(QStringList name_list)
{
QStringList new_name_list_; // 保存处理后的名称
QStringList sorted_list; // 保存需要排序的名称
QStringList regular_list; // 保存不需要排序的名称
for(int i = 0; i < name_list.size(); i++)
{
bool is_int;
name_list[i].split("_")[0].toInt(&is_int); // 将切割后的0索引字符穿转换为整数,如果转换成功 is_int 会变成 true
if(is_int)
{
sorted_list.append(name_list[i]);
}
else
{
// 如果是 false 说明名称格式是 "xxx" 格式
regular_list.append(name_list[i]);
}
}
std::sort(sorted_list.begin(), sorted_list.end(), [name_list, this](const QString& element1, const QString& element2)
{
return CompareElements(element1, element2, name_list);
});
// 将排序后名称添加到不需要排序的列表后面
regular_list.append(sorted_list);
///这里的切割部分是可以单独拿出来写一个函数,底部有封装好
// 将最后的列表进行切割过滤
for (const QString& element : regular_list)
{
QStringList parts = element.split("_");
bool is_int;
parts[0].toInt(&is_int);
if (is_int)
{
// 通过切割后的0索引的位置是否为整数来判断需要拿哪里的字符串
QString new_name = parts[1];
new_name_list_.append(station_name);
}
else
{
QString new_name = parts[0];
new_name_list_.append(station_name);
}
}
return new_name_list_;
}
// 排序函数,用于比较两个元素的第一个数字,如果数字相同则按照默认顺序排序
bool CompareElements(const QString& element1, const QString& element2, const QStringList& name_list)
{
int index1 = name_list.indexOf(element1);
int index2 = name_list.indexOf(element2);
QStringList parts1 = element1.split("_");
QStringList parts2 = element2.split("_");
int num1 = parts1[0].toInt();
int num2 = parts2[0].toInt();
if (num1 == num2)
{
return index1 < index2;
}
return num1 < num2;
}
// 将过滤好的名称进行还原
QString RestoreName(QString new_name)
{
QString name; // 用于记录切割后的名称
QString restored_name; // 记录原来的名字
for (const QString& element : sort_name_list_)
{
// 还是同理,通过将0索引的字符串转换为整数,通过转换结果进行相应的处理
QStringList parts = element.split("_");
bool is_int;
parts[0].toInt(&is_int);
is_int ? name = parts[1] : name = parts[0]; // 将name赋值为切割后的名字
if(name == new_name) // 判断切割后的名字和传入的名字是否相同
{
// 这里有一个弊端,就是若出现名称相同的人,则只会返回排序前面的名称
// 这里的优化留给感兴趣的朋友再次基础上优化这个问题
restored_name = element;
break;
}
}
qDebug() << "名称还原成功:" << restored_name;
return restored_name;
}
将切割函数进行封装
// 处理字符串列表
QStringList SimplifyStringList(QStringList name_list)
{
QStringList simplify_name;
for (const QString& element : name_list)
{
QStringList parts = element.split("_");
bool is_int;
parts[0].toInt(&is_int);
if (is_int)
{
QString station_name = parts[1];
simplify_name.append(station_name);
}
else
{
QString station_name = parts[0];
simplify_name.append(station_name);
}
}
return simplify_name;
}
// 处理单个字符串
QString SimplifyStringList(QString name_list)
{
QStringList parts = name_list.split("_");
bool is_int;
parts[0].toInt(&is_int);
if (is_int)
{
return parts[1];
}
else
{
return parts[0];
}
}
以上代码是我从自己的项目中截取并修改过的,上述这几行代码没有单独拿出来运行测试过,按理说应该没有问题(程序猿直觉)