alamb commented on pull request #984:
URL: https://github.com/apache/arrow-rs/pull/984#issuecomment-992700643
The other thing I can think of, that seems a bit of a hack, but might be ok
would be to take something like `impl TryInto<i128>` which covers all current
native types
```rust
/// Perform `left == right` operation on an array and a numeric scalar
/// value. Supports PrimtiveArrays, and DictionaryArrays that have primitive
values
pub fn eq_dyn_scalar<T>(
left: &dyn Array,
right: T
) -> Result<BooleanArray>
where
T : TryInto<i128> + Copy + std::fmt::Debug
{
let right: i128 = right
.try_into()
.map_err(|_| ArrowError::ComputeError(format!("Can not convert
scalar {:?} to i128", right)))?;
match left.data_type() {
DataType::UInt8 => {
let right: u8 = right
.try_into()
.map_err(|_| ArrowError::ComputeError(format!("Can not
convert {:?} to u8 for comparison with UInt8Array", right)))?;
eq_scalar::<UInt8Type>(as_primitive::<UInt8Type>(left), right)
}
DataType::UInt16 => {
let right: u16 = right
.try_into()
.map_err(|_| ArrowError::ComputeError(format!("Can not
convert {:?} to u16 for comparison with UInt16Array", right)))?;
eq_scalar::<UInt16Type>(as_primitive::<UInt16Type>(left), right)
}
// TODO macroize + fill out the other primitive array types here
DataType::Dictionary(key_type, value_type) => {
match key_type.as_ref() {
DataType::UInt8 => {
let left = as_dictionary::<UInt8Type>(left);
unpack_dict_comparison(left,
eq_dyn_scalar(left.values().as_ref(), right)?)
}
// TODO fill out the rest of the key types here
_ => todo!()
}
}
_ => todo!()
}
}
/// unpacks the results of comparing left.values (as a boolean)
///
/// TODO add example
///
fn unpack_dict_comparison<K>(
left: &DictionaryArray<K>,
dict_comparison: BooleanArray,
) -> Result<BooleanArray>
where
K: ArrowNumericType,
{
assert_eq!(dict_comparison.len(), left.values().len());
let result: BooleanArray = left
.keys()
.iter()
.map(|key| {
key.map(|key| unsafe {
// safety lengths were verified above
let key = key.to_usize().expect("Dictionary index not
usize");
dict_comparison.value_unchecked(key)
})
})
.collect();
Ok(result)
}
```
Which then finally allows a call to `eq_dyn_scalar` without type annotations:
```rust
#[test]
fn test_dict_eq_scalar() {
...
let array = builder.finish();
// YAY! No type annotations!
let a_eq = eq_dyn_scalar(&array, 123).unwrap();
assert_eq!(
a_eq,
BooleanArray::from(vec![Some(true), None, Some(false)])
);
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]