0

I want a list of strings sorted first by a number, and if the number is equal to 0, then sort it alphabetically.

Let's say I have :

struct numberedString{
     string s;
     int n;
}

I have an array numberedString a[] how do I sort the entries in the array using std::sort()? I think I first need to sort all the numberedString.s and then sort by the numberedString.n, but I don't see how exactly to do this ?

Buddy
  • 10,874
  • 5
  • 41
  • 58
Traxys
  • 85
  • 1
  • 1
  • 9
  • 1
    Start by writing a function that takes two `const struct numberedString&`s and returns whether the first is less than the second. – David Schwartz Sep 08 '15 at 22:35
  • 1
    possible duplicate of [c++ custom compare function for std::sort()](http://stackoverflow.com/questions/16894700/c-custom-compare-function-for-stdsort) – Bernhard Barker Sep 08 '15 at 22:37
  • "I want a list of string sorted by a number" - can you clarify what that even means? – ha9u63a7 Sep 08 '15 at 22:37

2 Answers2

1

Ask and you shall receive. Here you go.

Case 1: Specialized function object - functor.

struct functor
{
  bool operator() (const numberedString& a,
                   const numberedString& b)
  {
    if ((a.n != 0) && (b.n != 0))
    {
       return a.n < b.n;
    }
    return a.s < b.s;
  }
};

Case 2: Overloading operator < in structure.

struct numberedString
{
  string s;
  int n;
  bool operator<(const numberedString& other) const
  {
    if ((n != 0) && (other.n != 0))
    {
       return n < other.n;
    }
    return s < other.s;
  }
};

Usage:
Overloading the operator< allows functions to compare instances of your structure naturally:

  numberedString c, d;
  if (c < d)
  {
    cout << "c < d\n";
  }
  else
  {
    cout << "c >= d\n";
  }

The functor allows you to pass a comparison algorithm to ordering functions like std::sort:

   numberedString array[25];
   std::sort(&array[0], &array[25], functor);  

Note: See std::sort for exact syntax.

BTW, what are the rules for when one variable has a number of zero and the other doesn't?

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
  • Out-of-class `operator<` is preferred. The same for other comparison operators. See http://stackoverflow.com/questions/4421706/operator-overloading – user3427419 Sep 08 '15 at 23:03
  • Basically all the values with a `n!=0` are to be sorted numericaly within themsleves and the values where `n==0`are to be sorted alphabetically within themselves. At the end , all the values where `n!=0` are first then the others , all sorted – Traxys Sep 09 '15 at 18:30
-1

Basically your structure is so trivial that you could replace it with a std::pair.

using numberedString = std::pair<int, std::string>;

Then you could just use std::sort in the ordinary way and due to the std::pair lexicographical compare, you'll get you're desired effect, simple and without defining a custom comparator (example below):

#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <algorithm>

using numberedString = std::pair<int, std::string>;

int main() {
  numberedString vec1[] = {{4, "four"}, {2, "two"}, {1, "one"}};
  std::sort(std::begin(vec1), std::end(vec1));
  for(auto &&i : vec1) std::cout << i.first << " -- " << i.second << '\n';
  std::cout << std::endl;

  numberedString vec2[] = {{0, "four"}, {0, "two"}, {0, "one"}};
  std::sort(std::begin(vec2), std::end(vec2));
  for(auto &&i : vec2) std::cout << i.first << " -- " << i.second << '\n';
}

LIVE DEMO

101010
  • 41,839
  • 11
  • 94
  • 168
  • I guess the same reason why my answer was downvoted... We both read the question wrong. He wants to sort by the string only if the integers are both zero, not if they are equal. This is not a classical two-criteria-sorting which you solve with pairs (and me with tuples). – leemes Sep 08 '15 at 23:06
  • @leemes `He wants to sort by the string only if the integers are both zero` and so my code will. – 101010 Sep 08 '15 at 23:09
  • No, you also sort by the string if the integers are not zero but equal. Like `{{1, "z"}, {1, "a"}}` should be unchanged, but your code swaps the items. Your examples just don't cover this case ;) – leemes Sep 08 '15 at 23:10
  • @leemes where the OP says that? – 101010 Sep 08 '15 at 23:11
  • He wrote "sorted first by a number, and if the number is equal to 0, then sort it alphabetically." -- That means, if the number is not equal to 0, it shouldn't be sorted alphabetically. – leemes Sep 08 '15 at 23:12
  • @leemes "If the number is not equal to 0, it shouldn't be sorted alphabetically." this is nowhere in the OP's question. – 101010 Sep 08 '15 at 23:14
  • I didn't quote it. But I understand it like that, since he doesn't say what to do if it isn't equal to 0. He **only** wants to sort it alphabetically **if** it equals 0. You **always** sort it alphabetically if the numbers of the two objects are equal, which is also not mentioned in the question. It is indeed misleading, but your answer currently is wrong, so was mine. However I doubt that the OP actually wanted to say this (but he did). Anyways, I don't want to argue with you. I never said I downvoted your answer, by the way. – leemes Sep 08 '15 at 23:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89109/discussion-between-101010-and-leemes). – 101010 Sep 08 '15 at 23:17