1 /* PSPP - computes sample statistics.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include <data/case-ordering.h>
27 #include <data/dictionary.h>
28 #include <data/variable.h>
32 /* One key used for sorting. */
35 const struct variable *var; /* Variable. */
36 enum sort_direction dir; /* Sort direction. */
39 /* A set of criteria for ordering cases. */
42 size_t value_cnt; /* Number of `union value's per case. */
45 struct sort_key *keys;
49 struct case_ordering *
50 case_ordering_create (const struct dictionary *dict)
52 struct case_ordering *co = xmalloc (sizeof *co);
53 co->value_cnt = dict_get_next_value_idx (dict);
59 struct case_ordering *
60 case_ordering_clone (const struct case_ordering *orig)
62 struct case_ordering *co = xmalloc (sizeof *co);
63 co->value_cnt = orig->value_cnt;
64 co->keys = xmemdup (orig->keys, orig->key_cnt * sizeof *orig->keys);
65 co->key_cnt = orig->key_cnt;
70 case_ordering_destroy (struct case_ordering *co)
80 case_ordering_get_value_cnt (const struct case_ordering *co)
86 case_ordering_compare_cases (const struct ccase *a, const struct ccase *b,
87 const struct case_ordering *co)
91 for (i = 0; i < co->key_cnt; i++)
93 const struct sort_key *key = &co->keys[i];
94 int width = var_get_width (key->var);
99 double af = case_num (a, key->var);
100 double bf = case_num (b, key->var);
103 cmp = af > bf ? 1 : -1;
107 const char *as = case_str (a, key->var);
108 const char *bs = case_str (b, key->var);
109 cmp = memcmp (as, bs, width);
114 return key->dir == SRT_ASCEND ? cmp : -cmp;
120 case_ordering_add_var (struct case_ordering *co,
121 const struct variable *var, enum sort_direction dir)
123 struct sort_key *key;
126 for (i = 0; i < co->key_cnt; i++)
127 if (var_get_case_index (co->keys[i].var) == var_get_case_index (var))
130 co->keys = xnrealloc (co->keys, co->key_cnt + 1, sizeof *co->keys);
131 key = &co->keys[co->key_cnt++];
138 case_ordering_get_var_cnt (const struct case_ordering *co)
143 const struct variable *
144 case_ordering_get_var (const struct case_ordering *co, size_t idx)
146 assert (idx < co->key_cnt);
147 return co->keys[idx].var;
151 case_ordering_get_direction (const struct case_ordering *co, size_t idx)
153 assert (idx < co->key_cnt);
154 return co->keys[idx].dir;
158 case_ordering_get_vars (const struct case_ordering *co,
159 const struct variable ***vars, size_t *var_cnt)
163 *var_cnt = co->key_cnt;
164 *vars = xnmalloc (*var_cnt, sizeof **vars);
165 for (i = 0; i < co->key_cnt; i++)
166 (*vars)[i] = co->keys[i].var;