Reversing Array Vector Rows in DolphinDB Reactive State Engine: Does reverse(H:col) Work?
When processing streaming data with complex nested structures like array vectors in DolphinDB's Reactive State Engine, manipulating elements within individual rows is a common requirement. A frequent question developers ask is: Can we reverse row contents using syntax like reverse(H:col), and what does the H: prefix signify?
In this guide, we clarify the misconception around H:, explain why reverse() behaves differently, and show the exact, idiomatic approach to reversing array vectors row by row in DolphinDB.
Does reverse(H:arrCol) Work?
Short answer: No. reverse(H:arrCol) is not valid syntax in DolphinDB.
If you attempt to use H:arrCol inside createReactiveStateEngine, DolphinDB will throw a syntax error. The H: prefix does not exist as a keyword or modifier in DolphinDB. It often stems from confusion with other array-oriented languages (such as kdb+/q) or a mistaken belief that H: stands for "horizontal" vector manipulation.
Why Standard reverse() Doesn't Work Row-Wise
In DolphinDB, reverse() is designed to operate vertically (across historical rows in a column or on standard 1D vectors). When applied to an array vector:
reverse()expects to reverse the temporal order of rows (i.e., flipping record order across time windows), not the elements inside a specific row's array.- Inside a streaming engine where calculations are evaluated incrementally per incoming record, applying a temporal
reverse()without a defined rolling window causes type or state mismatch errors.
The Correct Solution: Use rowReverse()
To manipulate elements within each row of an array vector (horizontal processing), DolphinDB provides a dedicated family of row* functions. To invert the order of elements within each array (e.g., transforming [1, 2, 3] into [3, 2, 1]), use rowReverse.
Working Code Example
Here is a complete, minimal reproducible example demonstrating how to set up the Reactive State Engine with rowReverse:
// 1. Clean up any existing engine with the same name
try { dropStreamEngine("reverseEngine") } catch(ex) {}
// 2. Define schema for input stream and output table
share streamTable(1:0, `time`sym`arrCol, [TIMESTAMP, SYMBOL, INT[]]) as inputStream
output = table(100:0, `time`sym`reversed, [TIMESTAMP, SYMBOL, INT[]])
// 3. Create the Reactive State Engine using rowReverse
engine = createReactiveStateEngine(
name="reverseEngine",
metrics=<[rowReverse(arrCol) as reversed]>,
dummyTable=inputStream,
outputTable=output,
timeColumn=`time,
keyColumn=`sym
)
// 4. Subscribe the engine to the stream table
subscribeTable(tableName="inputStream", actionName="reverseSub", offset=0, handler=append!{engine}, msgAsTable=true)
// 5. Test with sample data
t = table(take(2023.10.01T09:30:00.000 + 1000 * (1..2), 2) as time,
`AAPL`MSFT as sym,
[[1, 2, 3], [10, 20, 30, 40]] as arrCol)
inputStream.append!(t)
// 6. Verify results
select * from output
Output
time sym reversed
----------------------- ---- ------------
2023.10.01T09:30:01.000 AAPL [3, 2, 1]
2023.10.01T09:30:02.000 MSFT [40, 30, 20, 10]
Key Takeaways for Array Vectors in Streaming Engines
- Use
row*functions for horizontal operations: For inner-array transformations, look for functions likerowReverse,rowSum,rowMin,rowMax, androwAvg. - Memory efficiency: Array vectors in DolphinDB store nested vectors contiguously in memory per record, making
row*functions significantly faster and more cache-friendly than applying higher-order looping functions likeeach. - Engine compatibility:
rowReverseis stateless and fully optimized for reactive state engines, executing with zero added latency on incoming stream bars or ticks.