PDA

View Full Version : Sorting a QList



vitalic
28th April 2020, 18:37
Hallo,

in my app the user has the possibility to add a station to a QListWidget. This works very well. After adding the station the list has to be updated. The problem, the QListWidget reads the stations and its frequency from a txt file.

So i need to sort the stations in the txt file not in the QListWidget, as I use the row index to tune to the station.

How can I sort the output before it is saved to the txt file?

The strings to campore look something like:

Jump,105600000
Station 1 93 MHz,93000000
man station@ 101.2MHz,101200000



ui->btn_rename->setVisible(true);

QString add_station = ui->ln_man_tune->text();
float add_station_float = add_station.toFloat();
int multi = add_station_float * 1000000;
QString station_conv_string = (QString::number(multi));

if(!add_station.isEmpty()){
QFile out_tmp("../tmp.txt");
QFile file_fm(path_fm);

if(!file_fm.open(QFile::ReadOnly | QFile::Text)){
return;
}

if(!out_tmp.open(QFile::WriteOnly | QFile::Text)){
return;
}

QTextStream in_file_fm(&file_fm);
file_fm.resize(0);
QTextStream out(&out_tmp);
QStringList unsort_scan_fm;

while(!in_file_fm.atEnd()){
QString line = in_file_fm.readLine();

QString outline = line;

unsort_scan_fm.append(outline);
}

if(add_station.contains(",")){
add_station = add_station.replace(",", ".");
}
if(!add_station.contains(".")){
add_station = add_station.append(".0");
}

//add new station at end of file
QString outline = "man station@ " + add_station + "MHz," + station_conv_string;

unsort_scan_fm.append(outline);
qDebug() << "before sort: :" << unsort_scan_fm;

std::sort(unsort_scan_fm.begin(), unsort_scan_fm.end());

qDebug() << "after sort: :" << unsort_scan_fm;

foreach(QString after_sort, unsort_scan_fm){
out << after_sort << "\n";
}

file_fm.close();
out_tmp.flush();
out_tmp.close();

file_fm.remove();
out_tmp.rename(path_fm);

ui->ls_fm->clear();

MainWindow::fill_list();
MainWindow::fm_list();
}


Debug before sort and after sort are the same:



after sort: : ("Jump,105600000", "Station 1 93 MHz,93000000", "Station 3 98.1 MHz,98100000", "Station 4 99.9 MHz,99900000", "Top40,94800000", "any station,107600000", "man station@ 100.2MHz,100200000", "man station@ 101.2MHz,101200000", "man station@ 101.3MHz,101300000", "man station@ 101.3MHz,101300000", "man station@ 104.6MHz,104600000", "man station@ 105.3MHz,105300000", "man station@ 105.4MHz,105400000", "man station@ 111.1MHz,111100000", "man station@ 96.8MHz,96800000", "man station@ 97.8MHz,97800000", "man station@ 99.9MHz,99900000", "zulu station,100700000")

ChrisW67
28th April 2020, 22:58
Hallo,


after sort: : ("Jump,105600000", "Station 1 93 MHz,93000000", "Station 3 98.1 MHz,98100000", "Station 4 99.9 MHz,99900000", "Top40,94800000", "any station,107600000", "man station@ 100.2MHz,100200000", "man station@ 101.2MHz,101200000", "man station@ 101.3MHz,101300000", "man station@ 101.3MHz,101300000", "man station@ 104.6MHz,104600000", "man station@ 105.3MHz,105300000", "man station@ 105.4MHz,105400000", "man station@ 111.1MHz,111100000", "man station@ 96.8MHz,96800000", "man station@ 97.8MHz,97800000", "man station@ 99.9MHz,99900000", "zulu station,100700000")

That looks like a case-sensitive string sort to me. Jump sorts before Station 1, which sorts before Station3 etc.

Were you expecting it to be sorted ignoring case, i.e. "any station,107600000", Jump ... then man ..., or to sort numerically on frequency?

Take a look at QStringList::sort() if you intended a case-insensitive string sort.
If you wanted a numeric sort then you have more work to do.

vitalic
30th April 2020, 09:04
I fixed the sort problem with this function:



QStringList MainWindow::sort_list(QStringList list){

QCollator coll;
coll.setNumericMode(true);

std::sort(list.begin(), list.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });

return list;
}