polars_plan/dsl/functions/
concat.rs1use super::*;
2
3#[cfg(all(feature = "concat_str", feature = "strings"))]
4pub fn concat_str<E: AsRef<[Expr]>>(s: E, separator: &str, ignore_nulls: bool) -> Expr {
6 let input = s.as_ref().to_vec();
7 let separator = separator.into();
8
9 Expr::Function {
10 input,
11 function: StringFunction::ConcatHorizontal {
12 delimiter: separator,
13 ignore_nulls,
14 }
15 .into(),
16 options: FunctionOptions {
17 collect_groups: ApplyOptions::ElementWise,
18 flags: FunctionFlags::default()
19 | FunctionFlags::INPUT_WILDCARD_EXPANSION & !FunctionFlags::RETURNS_SCALAR,
20 ..Default::default()
21 },
22 }
23}
24
25#[cfg(all(feature = "concat_str", feature = "strings"))]
26pub fn format_str<E: AsRef<[Expr]>>(format: &str, args: E) -> PolarsResult<Expr> {
28 let mut args: std::collections::VecDeque<Expr> = args.as_ref().to_vec().into();
29
30 let segments: Vec<&str> = format.split("{}").collect();
32
33 polars_ensure!(
34 segments.len() - 1 == args.len(),
35 ShapeMismatch: "number of placeholders should equal the number of arguments"
36 );
37
38 let mut exprs: Vec<Expr> = Vec::new();
39
40 for (i, s) in segments.iter().enumerate() {
41 if i > 0 {
42 if let Some(arg) = args.pop_front() {
43 exprs.push(arg);
44 }
45 }
46
47 if !s.is_empty() {
48 exprs.push(lit(s.to_string()))
49 }
50 }
51
52 Ok(concat_str(exprs, "", false))
53}
54
55pub fn concat_list<E: AsRef<[IE]>, IE: Into<Expr> + Clone>(s: E) -> PolarsResult<Expr> {
57 let s: Vec<_> = s.as_ref().iter().map(|e| e.clone().into()).collect();
58
59 polars_ensure!(!s.is_empty(), ComputeError: "`concat_list` needs one or more expressions");
60
61 Ok(Expr::Function {
62 input: s,
63 function: FunctionExpr::ListExpr(ListFunction::Concat),
64 options: FunctionOptions {
65 collect_groups: ApplyOptions::ElementWise,
66 flags: FunctionFlags::default() | FunctionFlags::INPUT_WILDCARD_EXPANSION,
67 ..Default::default()
68 },
69 })
70}
71
72pub fn concat_arr(input: Vec<Expr>) -> PolarsResult<Expr> {
74 feature_gated!("dtype-array", {
75 polars_ensure!(!input.is_empty(), ComputeError: "`concat_arr` needs one or more expressions");
76
77 Ok(Expr::Function {
78 input,
79 function: FunctionExpr::ArrayExpr(ArrayFunction::Concat),
80 options: FunctionOptions {
81 collect_groups: ApplyOptions::ElementWise,
82 flags: FunctionFlags::default() | FunctionFlags::INPUT_WILDCARD_EXPANSION,
83 ..Default::default()
84 },
85 })
86 })
87}
88
89pub fn concat_expr<E: AsRef<[IE]>, IE: Into<Expr> + Clone>(
90 s: E,
91 rechunk: bool,
92) -> PolarsResult<Expr> {
93 let s: Vec<_> = s.as_ref().iter().map(|e| e.clone().into()).collect();
94 polars_ensure!(!s.is_empty(), ComputeError: "`concat_expr` needs one or more expressions");
95
96 Ok(Expr::Function {
97 input: s,
98 function: FunctionExpr::ConcatExpr(rechunk),
99 options: FunctionOptions {
100 collect_groups: ApplyOptions::ElementWise,
101 flags: FunctionFlags::default() | FunctionFlags::INPUT_WILDCARD_EXPANSION,
102 cast_options: Some(CastingRules::cast_to_supertypes()),
103 ..Default::default()
104 },
105 })
106}