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}