Skip to main content

polars_ops/frame/
is_sorted.rs

1use polars_core::chunked_array::ops::SortOptions;
2use polars_core::chunked_array::ops::row_encode::_get_rows_encoded_ca;
3use polars_core::frame::DataFrame;
4use polars_core::prelude::*;
5use polars_error::{PolarsResult, polars_ensure};
6use polars_utils::itertools::Itertools;
7use polars_utils::pl_str::PlSmallStr;
8
9use crate::prelude::*;
10
11pub trait DataFrameIsSorted {
12    fn is_sorted(
13        &self,
14        by: &[PlSmallStr],
15        descending: &[bool],
16        nulls_last: &[bool],
17    ) -> PolarsResult<bool>;
18}
19
20impl DataFrameIsSorted for DataFrame {
21    fn is_sorted(
22        &self,
23        by: &[PlSmallStr],
24        descending: &[bool],
25        nulls_last: &[bool],
26    ) -> PolarsResult<bool> {
27        polars_ensure!(!by.is_empty(), InvalidOperation: "by must specify at least one column");
28        polars_ensure!(descending.len() == by.len(), InvalidOperation: "descending must be of same length as by");
29        polars_ensure!(nulls_last.len() == by.len(), InvalidOperation: "nulls_last must be of same length as by");
30
31        if let [by] = by {
32            let col = self.column(by)?;
33            return SeriesMethods::is_sorted(
34                col.as_materialized_series(),
35                SortOptions::new()
36                    .with_order_descending(descending[0])
37                    .with_nulls_last(nulls_last[0]),
38            );
39        }
40
41        let by_vec = by
42            .iter()
43            .map(|name| self.column(name).cloned())
44            .try_collect_vec()?;
45        let row_encoded =
46            _get_rows_encoded_ca(PlSmallStr::EMPTY, &by_vec, descending, nulls_last, false)?;
47        let s = Series::new(PlSmallStr::EMPTY, row_encoded);
48        SeriesMethods::is_sorted(&s, SortOptions::new())
49    }
50}