pub fn lexsort_to_indices(columns: &[SortColumn]) -> Result<PrimitiveArray<i32>> {
    if columns.is_empty() {
        return Err(ArrowError::InvalidArgumentError(
            "Sort requires at least one column".to_string(),
        ));
    }
    if columns.len() == 1 {
        // fallback to non-lexical sort
        let column = &columns[0];
        return sort_to_indices(column.values, &column.options.unwrap_or_default());
    }

    let row_count = columns[0].values.len();
    if columns.iter().any(|item| item.values.len() != row_count) {
        return Err(ArrowError::InvalidArgumentError(
            "lexical sort columns have different row counts".to_string(),
        ));
    };

    // map to data and DynComparator
    let flat_columns = columns
        .iter()
        .map(
            |column| -> Result<(&dyn Array, ord::DynComparator, SortOptions)> {
                // flatten and convert build comparators
                let array = column.values;
                Ok((
                    array,
                    ord::build_compare(array, array)?,
                    column.options.unwrap_or_default(),
                ))
            },
        )
        .collect::<Result<Vec<(&dyn Array, ord::DynComparator, SortOptions)>>>()?;

    let lex_comparator = |a_idx: &usize, b_idx: &usize| -> Ordering {
        for (array, comparator, sort_option) in flat_columns.iter() {
            match (array.is_valid(*a_idx), array.is_valid(*b_idx)) {
                (true, true) => {
                    match (comparator)(*a_idx, *b_idx) {
                        // equal, move on to next column
                        Ordering::Equal => continue,
                        order => {
                            if sort_option.descending {
                                return order.reverse();
                            } else {
                                return order;
                            }
                        }
                    }
                }
                (false, true) => {
                    return if sort_option.nulls_first {
                        Ordering::Less
                    } else {
                        Ordering::Greater
                    };
                }
                (true, false) => {
                    return if sort_option.nulls_first {
                        Ordering::Greater
                    } else {
                        Ordering::Less
                    };
                }
                // equal, move on to next column
                (false, false) => continue,
            }
        }

        Ordering::Equal
    };

    let mut value_indices = (0..row_count).collect::<Vec<usize>>();
    value_indices.sort_by(lex_comparator);

    let values = value_indices.into_iter().map(|i| i as i32);
    let values = unsafe { Buffer::<i32>::from_trusted_len_iter(values) };
    Ok(PrimitiveArray::<i32>::from_data(
        DataType::Int32,
        values,
        None,
    ))
}
/// Sort elements lexicographically from a list of `ArrayRef` into an unsigned integer
/// [`Int32Array`] of indices.
Sort elements lexicographically from a list of `ArrayRef` into an unsigned integer
[`Int32Array`] of indices.
Sort elements lexicographically from a list of ` ArrayRef ` into an unsigned integer [ ` Int32Array ` ] of indices .
pub fn lexsort_to_indices(columns: &[SortColumn]) -> Result<PrimitiveArray<i32>> {
    if columns.is_empty() {
        return Err(ArrowError::InvalidArgumentError(
            "Sort requires at least one column".to_string(),
        ));
    }
    if columns.len() == 1 {
        // fallback to non-lexical sort
        let column = &columns[0];
        return sort_to_indices(column.values, &column.options.unwrap_or_default());
    }
    let row_count = columns[0].values.len();
    if columns.iter().any(|item| item.values.len() != row_count) {
        return Err(ArrowError::InvalidArgumentError(
            "lexical sort columns have different row counts".to_string(),
        ));
    };
    // map to data and DynComparator
    let flat_columns = columns
        .iter()
        .map(
            |column| -> Result<(&dyn Array, ord::DynComparator, SortOptions)> {
                // flatten and convert build comparators
                let array = column.values;
                Ok((
                    array,
                    ord::build_compare(array, array)?,
                    column.options.unwrap_or_default(),
                ))
            },
        )
        .collect::<Result<Vec<(&dyn Array, ord::DynComparator, SortOptions)>>>()?;
    let lex_comparator = |a_idx: &usize, b_idx: &usize| -> Ordering {
        for (array, comparator, sort_option) in flat_columns.iter() {
            match (array.is_valid(*a_idx), array.is_valid(*b_idx)) {
                (true, true) => {
                    match (comparator)(*a_idx, *b_idx) {
                        // equal, move on to next column
                        Ordering::Equal => continue,
                        order => {
                            if sort_option.descending {
                                return order.reverse();
                            } else {
                                return order;
                            }
                        }
                    }
                }
                (false, true) => {
                    return if sort_option.nulls_first {
                        Ordering::Less
                    } else {
                        Ordering::Greater
                    };
                }
                (true, false) => {
                    return if sort_option.nulls_first {
                        Ordering::Greater
                    } else {
                        Ordering::Less
                    };
                }
                // equal, move on to next column
                (false, false) => continue,
            }
        }
        Ordering::Equal
    };
    let mut value_indices = (0..row_count).collect::<Vec<usize>>();
    value_indices.sort_by(lex_comparator);
    let values = value_indices.into_iter().map(|i| i as i32);
    let values = unsafe { Buffer::<i32>::from_trusted_len_iter(values) };
    Ok(PrimitiveArray::<i32>::from_data(
        DataType::Int32,
        values,
        None,
    ))
}
pub fn lexsort_to_indices ( columns : & [ SortColumn ] ) -> Result < PrimitiveArray < i32 > > { if columns . is_empty ( ) { return Err ( ArrowError :: InvalidArgumentError ( " " . to_string ( ) , ) ) ; } if columns . len ( ) == 1 { // fallback to non-lexical sort let column = & columns [ 0 ] ; return sort_to_indices ( column . values , & column . options . unwrap_or_default ( ) ) ; } let row_count = columns [ 0 ] . values . len ( ) ; if columns . iter ( ) . any ( | item | item . values . len ( ) != row_count ) { return Err ( ArrowError :: InvalidArgumentError ( " " . to_string ( ) , ) ) ; } ; // map to data and DynComparator let flat_columns = columns . iter ( ) . map ( | column | -> Result < ( & dyn Array , ord :: DynComparator , SortOptions ) > { // flatten and convert build comparators let array = column . values ; Ok ( ( array , ord :: build_compare ( array , array ) ? , column . options . unwrap_or_default ( ) , ) ) } , ) . collect :: < Result < Vec < ( & dyn Array , ord :: DynComparator , SortOptions ) > > > ( ) ? ; let lex_comparator = | a_idx : & usize , b_idx : & usize | -> Ordering { for ( array , comparator , sort_option ) in flat_columns . iter ( ) { match ( array . is_valid ( * a_idx ) , array . is_valid ( * b_idx ) ) { ( true , true ) => { match ( comparator ) ( * a_idx , * b_idx ) { // equal, move on to next column Ordering :: Equal => continue , order => { if sort_option . descending { return order . reverse ( ) ; } else { return order ; } } } } ( false , true ) => { return if sort_option . nulls_first { Ordering :: Less } else { Ordering :: Greater } ; } ( true , false ) => { return if sort_option . nulls_first { Ordering :: Greater } else { Ordering :: Less } ; } // equal, move on to next column ( false , false ) => continue , } } Ordering :: Equal } ; let mut value_indices = ( 0 .. row_count ) . collect :: < Vec < usize > > ( ) ; value_indices . sort_by ( lex_comparator ) ; let values = value_indices . into_iter ( ) . map ( | i | i as i32 ) ; let values = unsafe { Buffer :: < i32 > :: from_trusted_len_iter ( values ) } ; Ok ( PrimitiveArray :: < i32 > :: from_data ( DataType :: Int32 , values , None , ) ) }
Sort elements lexicographically from a list of `ArrayRef` into an unsigned integer
[`Int32Array`] of indices.
Sort elements lexicographically from a list of ` ArrayRef ` into an unsigned integer [ ` Int32Array ` ] of indices .
columns
&[SortColumn]
columns
&[SortColumn]