Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement collect for int values #2696

Closed
datapythonista opened this issue Sep 10, 2022 · 5 comments
Closed

Implement collect for int values #2696

datapythonista opened this issue Sep 10, 2022 · 5 comments
Labels
arrow Changes to the arrow crate

Comments

@datapythonista
Copy link
Contributor

Not sure if this is related to #169.

Maybe I'm missing something, but I guess it'd be nice if the next code worked:

vec![1, 2, 3].iter().collect::<Int32Array>();

By the error I'm getting, I assume it's just not implemented. If you can confirm that this would be nice to add, I'm happy to give it a try (any hints welcome, I'm not very experienced with rust). This is the error:

$ cargo run 
   Compiling arrow-examples v0.1.0 (/home/mgarcia/src/arrow-examples)
error[E0277]: the trait bound `arrow::array::array_primitive::NativeAdapter<Int32Type>: From<&{integer}>` is not satisfied
    --> src/main.rs:18:26
     |
18   |     vec![1, 2, 3].iter().collect::<Int32Array>()
     |                          ^^^^^^^ the trait `From<&{integer}>` is not implemented for `arrow::array::array_primitive::NativeAdapter<Int32Type>`
     |
     = help: the following other types implement trait `From<T>`:
               <arrow::array::array_primitive::NativeAdapter<Float16Type> as From<half::binary16::f16>>
               <arrow::array::array_primitive::NativeAdapter<Float32Type> as From<f32>>
               <arrow::array::array_primitive::NativeAdapter<Float64Type> as From<f64>>
               <arrow::array::array_primitive::NativeAdapter<Int16Type> as From<i16>>
               <arrow::array::array_primitive::NativeAdapter<Int32Type> as From<i32>>
               <arrow::array::array_primitive::NativeAdapter<Int64Type> as From<i64>>
               <arrow::array::array_primitive::NativeAdapter<Int8Type> as From<i8>>
               <arrow::array::array_primitive::NativeAdapter<T> as From<&Option<<T as ArrowPrimitiveType>::Native>>>
             and 5 others
     = note: required because of the requirements on the impl of `Into<arrow::array::array_primitive::NativeAdapter<Int32Type>>` for `&{integer}`
     = note: required because of the requirements on the impl of `FromIterator<&{integer}>` for `PrimitiveArray<Int32Type>`
note: required by a bound in `collect`
    --> /home/mgarcia/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1788:19
     |
1788 |     fn collect<B: FromIterator<Self::Item>>(self) -> B
     |                   ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `arrow-examples` due to previous error
@tustvold
Copy link
Contributor

The following will work

vec![1, 2, 3].into_iter().collect::<Int32Array>();
vec![1, 2, 3].iter().copied().collect::<Int32Array>();

I think this could be extended to support &i32, etc... by defining From<&i32> for NativeAdapter<i32>. Is this what you're after, or are the above solutions sufficient?

@datapythonista
Copy link
Contributor Author

Thanks a lot for the fast answer @tustvold . I think your first example is what I want. I'm not so familiar with iterators, and similar examples that I saw used iter, not into_iter. Let me research a bit to understand better, but it should be enough.

@datapythonista
Copy link
Contributor Author

I had a look, and the code you shared works great for integer, but for a string array seems it fails:

vec!["foo", "bar", "foobar"].iter().collect::<StringArray>()
   Compiling arrow-cookbook v0.1.0 (/home/mgarcia/src/arrow-cookbook)
error[E0277]: a value of type `GenericStringArray<i32>` cannot be built from an iterator over elements of type `&str`
    --> src/create_arrays.rs:90:46
     |
90   |     vec!["foo", "bar", "foobar"].into_iter().collect::<StringArray>()
     |                                              ^^^^^^^ value of type `GenericStringArray<i32>` cannot be built from `std::iter::Iterator<Item=&str>`
     |
     = help: the trait `FromIterator<&str>` is not implemented for `GenericStringArray<i32>`
     = help: the following other types implement trait `FromIterator<A>`:
               <GenericStringArray<OffsetSize> as FromIterator<&'a Option<Ptr>>>
               <GenericStringArray<OffsetSize> as FromIterator<Option<Ptr>>>
note: required by a bound in `collect`
    --> /home/mgarcia/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1788:19
     |
1788 |     fn collect<B: FromIterator<Self::Item>>(self) -> B
     |                   ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `arrow-cookbook` due to previous error

shell returned 101

Is this expected? Is there another syntax for this, or it just doesn't work for StringArray?

Thank you!

@tustvold
Copy link
Contributor

We've not implemented a NativeAdapter for StringArray yet, so you can only collect an iterator of Option<&str>

So

["A',"b"].into_iter().map(Some).collect::<StringArray>()

[Some("A'),Some("b")].into_iter().map(Some).collect::<StringArray>()

Alternatively you can use https://docs.rs/arrow/22.0.0/arrow/array/struct.GenericStringArray.html#method.from_iter_values

@datapythonista
Copy link
Contributor Author

Ah, I see. Thanks a lot for the help. I may give it a try and see if I can implement it. Closing this issue.

@alamb alamb added the arrow Changes to the arrow crate label Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrow Changes to the arrow crate
Projects
None yet
Development

No branches or pull requests

3 participants