GitHub user ryux1 closed the discussion with a comment: How to use builders in
a loop to build array of lists of structs?
The simplest pattern is to keep each mutable borrow shorter than the next
builder operation. A small helper makes that explicit and avoids repeating the
chained calls:
```rust
fn append_entry(builder: &mut StructBuilder, key: &str, value: &str) {
{
let (key_fields, value_fields) =
builder.field_builders_mut().split_at_mut(1);
key_fields[0]
.as_any_mut()
.downcast_mut::<StringBuilder>()
.unwrap()
.append_value(key);
value_fields[0]
.as_any_mut()
.downcast_mut::<StringBuilder>()
.unwrap()
.append_value(value);
} // the child-builder borrows end here
builder.append(true);
}
let mut list_builder =
ListBuilder::new(StructBuilder::from_fields(fields_of_key_and_value, 0));
for map in maps {
for (key, value) in map {
append_entry(list_builder.values(), key, value);
}
// One list slot per map / outer row, not one per key-value struct.
list_builder.append(true);
}
let array = list_builder.finish();
```
There are two separate borrow conflicts in the original code:
1. Holding `key_builder` / `value_builder` keeps `struct_builder` mutably
borrowed, so `struct_builder.append(true)` cannot run until those references
leave scope.
2. Holding `struct_builder = list_builder.values()` keeps `list_builder`
borrowed, so `list_builder.append(true)` must happen after that borrow ends.
The helper handles both: `list_builder.values()` is borrowed only for the call,
and the inner scope releases the two field builders before appending the struct
validity bit.
Also, each struct row must append exactly one value (or null) to every child
builder before `StructBuilder::append`; that consistency is required by the
builder contract: [current
source](https://github.com/apache/arrow-rs/blob/main/arrow-array/src/builder/struct_builder.rs#L213-L217).
GitHub link:
https://github.com/apache/arrow-rs/discussions/9483#discussioncomment-18317816
----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]