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