From 24fa10d342460c0c2e6a5b80d1e4cf50b5f2c225 Mon Sep 17 00:00:00 2001 From: Philip Sampaio Date: Wed, 7 Feb 2024 15:14:03 -0300 Subject: [PATCH] Fix `from_list/2` of list of structs when first is empty (#849) * Fix `from_list/2` of list of structs when fist is empty Closes https://github.com/elixir-explorer/explorer/issues/847 * Update test/explorer/series/list_test.exs --- lib/explorer/polars_backend/shared.ex | 10 +++++++++- test/explorer/series/list_test.exs | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/explorer/polars_backend/shared.ex b/lib/explorer/polars_backend/shared.ex index 56c2df183..b652b2aa3 100644 --- a/lib/explorer/polars_backend/shared.ex +++ b/lib/explorer/polars_backend/shared.ex @@ -126,7 +126,7 @@ defmodule Explorer.PolarsBackend.Shared do Native.s_from_list_of_series(name, series) end - def from_list(list, {:struct, fields} = _dtype, name) when is_list(list) do + def from_list(list, {:struct, fields} = dtype, name) when is_list(list) do series = for {column, values} <- Table.to_columns(list) do column = to_string(column) @@ -135,6 +135,14 @@ defmodule Explorer.PolarsBackend.Shared do end Native.s_from_list_of_series_as_structs(name, series) + |> then(fn polars_series -> + if Native.s_dtype(polars_series) != dtype do + {:ok, casted} = Native.s_cast(polars_series, dtype) + casted + else + polars_series + end + end) end def from_list(list, dtype, name) when is_list(list) do diff --git a/test/explorer/series/list_test.exs b/test/explorer/series/list_test.exs index abd2fc30a..f5a9daaf8 100644 --- a/test/explorer/series/list_test.exs +++ b/test/explorer/series/list_test.exs @@ -168,6 +168,22 @@ defmodule Explorer.Series.ListTest do "the value \"z\" does not match the inferred dtype {:s, 64}", fn -> Series.from_list([[[[[1, 2], ["z", "b"]]]]]) end end + + test "list of structs" do + series = + Series.from_list([[%{"a" => 42}], []], dtype: {:list, {:struct, %{"a" => :integer}}}) + + assert Series.dtype(series) == {:list, {:struct, %{"a" => {:s, 64}}}} + assert Series.to_list(series) == [[%{"a" => 42}], []] + end + + test "list of structs with first empty" do + series = + Series.from_list([[], [%{"a" => 42}], []], dtype: {:list, {:struct, %{"a" => :integer}}}) + + assert Series.dtype(series) == {:list, {:struct, %{"a" => {:s, 64}}}} + assert Series.to_list(series) == [[], [%{"a" => 42}], []] + end end describe "cast/2" do