polars_core/chunked_array/ops/sort/options.rs
1#[cfg(feature = "serde-lazy")]
2use serde::{Deserialize, Serialize};
3pub use slice::*;
4
5use crate::prelude::*;
6
7/// Options for single series sorting.
8///
9/// Indicating the order of sorting, nulls position, multithreading, and maintaining order.
10///
11/// # Example
12///
13/// ```
14/// # use polars_core::prelude::*;
15/// let s = Series::new("a".into(), [Some(5), Some(2), Some(3), Some(4), None].as_ref());
16/// let sorted = s
17/// .sort(
18/// SortOptions::default()
19/// .with_order_descending(true)
20/// .with_nulls_last(true)
21/// .with_multithreaded(false),
22/// )
23/// .unwrap();
24/// assert_eq!(
25/// sorted,
26/// Series::new("a".into(), [Some(5), Some(4), Some(3), Some(2), None].as_ref())
27/// );
28/// ```
29#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
30#[cfg_attr(feature = "serde-lazy", derive(Serialize, Deserialize))]
31pub struct SortOptions {
32 /// If true sort in descending order.
33 /// Default `false`.
34 pub descending: bool,
35 /// Whether place null values last.
36 /// Default `false`.
37 pub nulls_last: bool,
38 /// If true sort in multiple threads.
39 /// Default `true`.
40 pub multithreaded: bool,
41 /// If true maintain the order of equal elements.
42 /// Default `false`.
43 pub maintain_order: bool,
44 /// Limit a sort output, this is for optimization purposes and might be ignored.
45 pub limit: Option<IdxSize>,
46}
47
48/// Sort options for multi-series sorting.
49///
50/// Indicating the order of sorting, nulls position, multithreading, and maintaining order.
51///
52/// # Example
53/// ```
54/// # use polars_core::prelude::*;
55///
56/// # fn main() -> PolarsResult<()> {
57/// let df = df! {
58/// "a" => [Some(1), Some(2), None, Some(4), None],
59/// "b" => [Some(5), None, Some(3), Some(2), Some(1)]
60/// }?;
61///
62/// let out = df
63/// .sort(
64/// ["a", "b"],
65/// SortMultipleOptions::default()
66/// .with_maintain_order(true)
67/// .with_multithreaded(false)
68/// .with_order_descending_multi([false, true])
69/// .with_nulls_last(true),
70/// )?;
71///
72/// let expected = df! {
73/// "a" => [Some(1), Some(2), Some(4), None, None],
74/// "b" => [Some(5), None, Some(2), Some(3), Some(1)]
75/// }?;
76///
77/// assert_eq!(out, expected);
78///
79/// # Ok(())
80/// # }
81#[derive(Clone, Debug, Eq, PartialEq, Hash)]
82#[cfg_attr(feature = "serde-lazy", derive(Serialize, Deserialize))]
83pub struct SortMultipleOptions {
84 /// Order of the columns. Default all `false``.
85 ///
86 /// If only one value is given, it will broadcast to all columns.
87 ///
88 /// Use [`SortMultipleOptions::with_order_descending_multi`]
89 /// or [`SortMultipleOptions::with_order_descending`] to modify.
90 ///
91 /// # Safety
92 ///
93 /// Len must match the number of columns, or equal 1.
94 pub descending: Vec<bool>,
95 /// Whether place null values last. Default `false`.
96 pub nulls_last: Vec<bool>,
97 /// Whether sort in multiple threads. Default `true`.
98 pub multithreaded: bool,
99 /// Whether maintain the order of equal elements. Default `false`.
100 pub maintain_order: bool,
101 /// Limit a sort output, this is for optimization purposes and might be ignored.
102 pub limit: Option<IdxSize>,
103}
104
105impl Default for SortOptions {
106 fn default() -> Self {
107 Self {
108 descending: false,
109 nulls_last: false,
110 multithreaded: true,
111 maintain_order: false,
112 limit: None,
113 }
114 }
115}
116
117impl Default for SortMultipleOptions {
118 fn default() -> Self {
119 Self {
120 descending: vec![false],
121 nulls_last: vec![false],
122 multithreaded: true,
123 maintain_order: false,
124 limit: None,
125 }
126 }
127}
128
129impl SortMultipleOptions {
130 /// Create `SortMultipleOptions` with default values.
131 pub fn new() -> Self {
132 Self::default()
133 }
134
135 /// Specify order for each column. Defaults all `false`.
136 ///
137 /// # Safety
138 ///
139 /// Len must match the number of columns, or be equal to 1.
140 pub fn with_order_descending_multi(
141 mut self,
142 descending: impl IntoIterator<Item = bool>,
143 ) -> Self {
144 self.descending = descending.into_iter().collect();
145 self
146 }
147
148 /// Sort order for all columns. Default `false` which is ascending.
149 pub fn with_order_descending(mut self, descending: bool) -> Self {
150 self.descending = vec![descending];
151 self
152 }
153
154 /// Specify whether to place nulls last, per-column. Defaults all `false`.
155 ///
156 /// # Safety
157 ///
158 /// Len must match the number of columns, or be equal to 1.
159 pub fn with_nulls_last_multi(mut self, nulls_last: impl IntoIterator<Item = bool>) -> Self {
160 self.nulls_last = nulls_last.into_iter().collect();
161 self
162 }
163
164 /// Whether to place null values last. Default `false`.
165 pub fn with_nulls_last(mut self, enabled: bool) -> Self {
166 self.nulls_last = vec![enabled];
167 self
168 }
169
170 /// Whether to sort in multiple threads. Default `true`.
171 pub fn with_multithreaded(mut self, enabled: bool) -> Self {
172 self.multithreaded = enabled;
173 self
174 }
175
176 /// Whether to maintain the order of equal elements. Default `false`.
177 pub fn with_maintain_order(mut self, enabled: bool) -> Self {
178 self.maintain_order = enabled;
179 self
180 }
181
182 /// Reverse the order of sorting for each column.
183 pub fn with_order_reversed(mut self) -> Self {
184 self.descending.iter_mut().for_each(|x| *x = !*x);
185 self
186 }
187}
188
189impl SortOptions {
190 /// Create `SortOptions` with default values.
191 pub fn new() -> Self {
192 Self::default()
193 }
194
195 /// Specify sorting order for the column. Default `false`.
196 pub fn with_order_descending(mut self, enabled: bool) -> Self {
197 self.descending = enabled;
198 self
199 }
200
201 /// Whether place null values last. Default `false`.
202 pub fn with_nulls_last(mut self, enabled: bool) -> Self {
203 self.nulls_last = enabled;
204 self
205 }
206
207 /// Whether sort in multiple threads. Default `true`.
208 pub fn with_multithreaded(mut self, enabled: bool) -> Self {
209 self.multithreaded = enabled;
210 self
211 }
212
213 /// Whether maintain the order of equal elements. Default `false`.
214 pub fn with_maintain_order(mut self, enabled: bool) -> Self {
215 self.maintain_order = enabled;
216 self
217 }
218
219 /// Reverse the order of sorting.
220 pub fn with_order_reversed(mut self) -> Self {
221 self.descending = !self.descending;
222 self
223 }
224}
225
226impl From<&SortOptions> for SortMultipleOptions {
227 fn from(value: &SortOptions) -> Self {
228 SortMultipleOptions {
229 descending: vec![value.descending],
230 nulls_last: vec![value.nulls_last],
231 multithreaded: value.multithreaded,
232 maintain_order: value.maintain_order,
233 limit: value.limit,
234 }
235 }
236}
237
238impl From<&SortMultipleOptions> for SortOptions {
239 fn from(value: &SortMultipleOptions) -> Self {
240 SortOptions {
241 descending: value.descending.first().copied().unwrap_or(false),
242 nulls_last: value.nulls_last.first().copied().unwrap_or(false),
243 multithreaded: value.multithreaded,
244 maintain_order: value.maintain_order,
245 limit: value.limit,
246 }
247 }
248}