Handle empty lines properly in numeric sort.

pull/44/head
Andreas Jönsson 10 years ago
parent 936d9c56fc
commit ee225f5cad

@ -778,13 +778,16 @@ int stoiStrict(const generic_string& input)
} }
} }
bool allLinesAreNumeric(const std::vector<generic_string>& lines) bool allLinesAreNumericOrEmpty(const std::vector<generic_string>& lines)
{ {
for (const generic_string& line : lines) for (const generic_string& line : lines)
{ {
try try
{ {
stoiStrict(line); if (!line.empty())
{
stoiStrict(line);
}
} }
catch (std::invalid_argument&) catch (std::invalid_argument&)
{ {
@ -798,6 +801,18 @@ bool allLinesAreNumeric(const std::vector<generic_string>& lines)
return true; return true;
} }
std::vector<generic_string> repeatString(const generic_string& text, const size_t count)
{
std::vector<generic_string> output;
output.reserve(count);
for (size_t i = 0; i < count; ++i)
{
output.push_back(text);
}
assert(output.size() == count);
return output;
}
std::vector<generic_string> lexicographicSort(std::vector<generic_string> input, bool isDescending) std::vector<generic_string> lexicographicSort(std::vector<generic_string> input, bool isDescending)
{ {
std::sort(input.begin(), input.end(), [isDescending](generic_string a, generic_string b) std::sort(input.begin(), input.end(), [isDescending](generic_string a, generic_string b)
@ -816,14 +831,24 @@ std::vector<generic_string> lexicographicSort(std::vector<generic_string> input,
std::vector<generic_string> numericSort(std::vector<generic_string> input, bool isDescending) std::vector<generic_string> numericSort(std::vector<generic_string> input, bool isDescending)
{ {
// Pre-condition: all strings in "input" are convertible to int with stoiStrict. // Pre-condition: all strings in "input" are either empty or convertible to int with stoiStrict.
std::vector<int> inputAsInts; // Note that empty lines are filtered out and added back manually to the output at the end.
inputAsInts.reserve(input.size()); std::vector<int> nonEmptyinputAsInts;
size_t nofEmptyLines = 0;
nonEmptyinputAsInts.reserve(input.size());
for (const generic_string& line : input) for (const generic_string& line : input)
{ {
inputAsInts.push_back(stoiStrict(line)); if (line.empty())
{
++nofEmptyLines;
}
else
{
nonEmptyinputAsInts.push_back(stoiStrict(line));
}
} }
std::sort(inputAsInts.begin(), inputAsInts.end(), [isDescending](int a, int b) assert(nonEmptyinputAsInts.size() + nofEmptyLines == input.size());
std::sort(nonEmptyinputAsInts.begin(), nonEmptyinputAsInts.end(), [isDescending](int a, int b)
{ {
if (isDescending) if (isDescending)
{ {
@ -836,9 +861,19 @@ std::vector<generic_string> numericSort(std::vector<generic_string> input, bool
}); });
std::vector<generic_string> output; std::vector<generic_string> output;
output.reserve(input.size()); output.reserve(input.size());
for (const int& sortedInt : inputAsInts) const std::vector<generic_string> empties = repeatString(TEXT(""), nofEmptyLines);
if (!isDescending)
{
output.insert(output.end(), empties.begin(), empties.end());
}
for (const int& sortedInt : nonEmptyinputAsInts)
{ {
output.push_back(std::to_wstring(sortedInt)); output.push_back(std::to_wstring(sortedInt));
} }
if (isDescending)
{
output.insert(output.end(), empties.begin(), empties.end());
}
assert(output.size() == input.size());
return output; return output;
} }

@ -191,7 +191,8 @@ generic_string stringReplace(generic_string subject, const generic_string& searc
std::vector<generic_string> stringSplit(const generic_string& input, const generic_string& delimiter); std::vector<generic_string> stringSplit(const generic_string& input, const generic_string& delimiter);
generic_string stringJoin(const std::vector<generic_string>& strings, const generic_string& separator); generic_string stringJoin(const std::vector<generic_string>& strings, const generic_string& separator);
int stoiStrict(const generic_string& input); int stoiStrict(const generic_string& input);
bool allLinesAreNumeric(const std::vector<generic_string>& lines); bool allLinesAreNumericOrEmpty(const std::vector<generic_string>& lines);
std::vector<generic_string> repeatString(const generic_string& text, const size_t count);
std::vector<generic_string> numericSort(std::vector<generic_string> input, bool isDescending); std::vector<generic_string> numericSort(std::vector<generic_string> input, bool isDescending);
std::vector<generic_string> lexicographicSort(std::vector<generic_string> input, bool isDescending); std::vector<generic_string> lexicographicSort(std::vector<generic_string> input, bool isDescending);

@ -2968,7 +2968,7 @@ void ScintillaEditView::sortLines(size_t fromLine, size_t toLine, bool isDescend
} }
} }
assert(toLine - fromLine + 1 == splitText.size()); assert(toLine - fromLine + 1 == splitText.size());
const bool isNumericSort = allLinesAreNumeric(splitText); const bool isNumericSort = allLinesAreNumericOrEmpty(splitText);
std::vector<generic_string> sortedText; std::vector<generic_string> sortedText;
if (isNumericSort) if (isNumericSort)
{ {

Loading…
Cancel
Save