# Sequence Manipulator C Functions

> The following sequence manipulator C functions take a variety of input sequence arguments and produce result sequences as described in the table below:

> mco_seq_filter_first_pos() | Return in integer sequence result the first n positions of `true` elements in the boolean sequence cond.
>         MCO_RET mco_seq_filter_first_pos(mco_seq_iterator_h result,
>                  mco_seq_iterator_h cond,
>                 mco_size_t n);
> mco_seq_reverse_TYPE() | Reverse the elements of the input sequence.
>         MCO_RET mco_seq_reverse_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input);
> mco_seq_concat() | Concatenate two sequences of any type by appending sequence right to sequence left. The result sequence will be of the same type as left and right.
>         MCO_RET mco_seq_concat(mco_seq_iterator_h result,
>                 mco_seq_iterator_h left,
>                 mco_seq_iterator_h right);
> mco_seq_cat() | Concatenate two sequences of any type by appending sequence right to sequence left. The result sequence will be of type `char`.
>         MCO_RET mco_seq_cat(mco_seq_iterator_h result,
>                 mco_seq_iterator_h left,
>                 mco_seq_iterator_h right);
> mco_seq_limit_TYPE() | Copy to the result sequence the sub-sequence from the input using sequence positions from and till.
>         MCO_RET mco_seq_limit_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input,
>                 mco_seq_no_t from,
>                 mco_seq_no_t till);
> mco_seq_get_TYPE() | Extract data from the input sequence to the buffer buf whose length is specified by parameter size. On success the return value is `MCO_S_OK` and parameter size contains the number of elements actually placed in the buffer.
>         MCO_RET mco_seq_get_TYPE(mco_seq_iterator_h input,
>                 TYPE* buf,
>                 mco_size_t* size);
> mco_seq_get_nullable_TYPE() | Extract data, including nulls, from the input sequence to the buffer buf whose length is specified by parameter size. On success the return value is `MCO_S_OK` and parameter size contains the number of elements actually placed in the buffer. Parameter nulls is a bitmap indicating null values in the sequence.
>         MCO_RET mco_seq_get_TYPE(mco_seq_iterator_h input,
>                 TYPE* buf,
>                 mco_size_t* size,
>                 mco_bitmap_word_t const * nulls);
> mco_seq_unget_TYPE() | Iterate through the elements of the buffer buf previously created with `mco_seq_get_TYPE()` to return sequence result of the same type. Parameter buf_size is the length of the buffer.
>         MCO_RET mco_seq_unget_TYPE(mco_seq_iterator_h result,
>                 TYPE const* buf,
>                 mco_size_t buf_size);
> mco_seq_unget_nullable_TYPE() | Iterate through the elements, including nulls, of the buffer buf previously created with `mco_seq_get_TYPE()` to return sequence result of the same type. Parameter buf_size is the length of the buffer. Parameter nulls is a bitmap indicating null values in the sequence.
>         MCO_RET mco_seq_unget_TYPE(mco_seq_iterator_h result,
>                 TYPE const* buf,
>                 mco_size_t buf_size
>                 mco_bitmap_word_t const * nulls);
> mco_seq_uniq_TYPE() | Copy to the result sequence only the unique elements in ordered sequence input by "collapsing duplicates".
>         MCO_RET mco_seq_uniq_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input);
> mco_seq_skip_nan_TYPE() | Copy the input sequence to result skipping `NaN` (Not-a-Number) elements. (Please see the `mco_seq_skip_nan_TYPE()` page for further details on this API.)
>         MCO_RET mco_seq_skip_nan_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input);
> mco_seq_norm_TYPE() | Return in result the normalized input sequence; i.e. divide each sequence element by the square root of the sum of squares of all elements.
>         MCO_RET mco_seq_norm_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input);
> mco_seq_thin_TYPE() | Copy the input sequence to result selecting elements with the specified origin and step.
>         MCO_RET mco_seq_thin_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input,
>                 mco_size_t origin,
>                 mco_size_t step);
> mco_seq_diff_TYPE() | Return in result the differences between pairs of sequence elements in input.
>         MCO_RET mco_seq_diff_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input);
> mco_seq_trend_TYPE() | Return in result the " trend" by comparing pairs of sequence elements in input: the sign of the difference between pairs of non-equal sequence elements. For example, the input sequence `{1,2,3,3,2,2,4,5,6,5,5}` would produce the result `{0,1,1,1,-1,-1,1,1,1,-1,-1}`.
>         MCO_RET mco_seq_trend_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input);
> mco_seq_const_TYPE() | Construct sequence result with elements having the constant value val. (Note that there is no length argument so the result sequence is effectively infinite, you can call `mco_seq_next()` on it forever.)
>         MCO_RET mco_seq_const_TYPE(mco_seq_iterator_h result,
>                 TYPE val);
> mco_seq_parse_TYPE() | Construct sequence result from the string literal str, e.g. "{1.0, -1.1, 0}".
>         MCO_RET mco_seq_parse_TYPE(mco_seq_iterator_h result,
>                 char const* str);
> mco_seq_join_TYPE() | Use a metaiterator to combine multiple sequences. (Please see the seq_join function page for a more detailed explanation.)
>         MCO_RET mco_seq_join_TYPE(mco_seq_iterator_h result,
>                 mco_seq_meta_iterator_h meta_iterator);
> mco_seq_union_TYPE() | Return in result the union of the two ordered sequences left and right using the specified order. Note that result will contain different elements from both input sequences.
>         MCO_RET mco_seq_union_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h left,
>                 mco_seq_iterator_h right,
>                 mco_seq_order_t order);
> mco_seq_tee() | Create two iterators for the same input sequence (i.e. fork the sequence iterator). (Note that these iterators should be traversed together (i.e. used in the same expression). The input sequence can be of any type.
>         MCO_RET mco_seq_tee(mco_seq_iterator_h iterator1,
>                 mco_seq_iterator_h iterator2,
>                 mco_seq_iterator_h input);
> mco_seq_map_TYPE() | Return in result the elements extracted from the input sequence using the positions specified in the positions sequence. The positions should be provided in ascending order. (Note that while most of the sequence functions returning positions, like `mco_seq_filter_pos()`, return positions in ascending order, mco_seq_top_pos_TYPE() obviously violates this rule.)
>         MCO_RET mco_seq_map_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input,
>                 mco_seq_iterator_h positions);
> mco_seq_repeat_TYPE() | Return in result each element of the input sequence repeated n_times times.
>         MCO_RET mco_seq_repeat_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input,
>                 int n_times);
> mco_seq_stretch_TS_TYPE_VAL_TYPE() | Return in result the elements of the values sequence stretched to the length of the ts1 sequence by repeating the elements of values while the corresponding timestamp in sequence ts2 is larger than timestamp from ts1. Use the filler values for elements where the corresponding timestamp in sequence ts2 is less than timestamp from ts1. For example, assume ts1 = `{1,2,3,4,5}`, ts2 = `{2,4}`, values = `{1.1,2.2}` and filler =`1.0`. With these input sequences the result will be `{1.1,2.2,2.2,1.0,1.0}`. (This function can be used to calculate split adjusted price where it is necessary to revert time series of splits, calculate the cumulative product and multiply on price.)
>         MCO_RET mco_seq_stretch_TS_TYPE1_VAL_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h ts1,
>                 mco_seq_iterator_h ts2,
>                 mco_seq_iterator_h values,
>                 TYPE2 filler);
> mco_seq_stretch0_TS_TYPE_VAL_TYPE() | Return in result the elements of the values and filler sequences by injecting the elements of values where the corresponding timestamps in sequence ts2 match the timestamp from ts1. Use the filler values for elements where the timestamp in sequence ts2 has no matching timestamp in ts1. For example, assume ts1 = `{1,2,3,5}`, ts2 = `{2,3,4}`, values = `{1.1,1.2,1.3}` and filler = `0.0`. With these input sequences the result will be `{0.0,1.1,1.2,1.3,0.0}`.
>         MCO_RET mco_seq_stretch0_TS_TYPE1_VAL_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h ts1,
>                 mco_seq_iterator_h ts2,
>                 mco_seq_iterator_h values,
>                 TYPE2 filler);
> mco_seq_asof_join_TS_TYPE_VAL_TYPE() | Return in result the elements of the values sequence corresponding to the timestamp of ts2 closest to the timestamp of ts1. For example, assume ts1 = `{4,9}`, ts2 = `{1,3,6,10}`, and values = `{0.1,0.3,0.6,1.0}`. With these input sequences the result will be `{0.3,1.0}` .
>         MCO_RET mco_seq_asof_join_TS_TYPE1_VAL_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h ts1,
>                 mco_seq_iterator_h ts2,
>                 mco_seq_iterator_h values);
> mco_seq_cross_TYPE() | Return in result the positions in the input sequence where it crosses zero. If the integer argument first_cross_direction is positive then the result sequence starts with the first cross above zero; if negative it starts with cross below zero; if first_cross_direction is zero then it doesn't matter, i.e. the first cross can be above or below zero.
>         MCO_RET mco_seq_cross_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input,
>                 int first_cross_direction);
> mco_seq_extrema_TYPE() | Return in result the positions of extrema (local minimum and maximums) in the input sequence. If the integer argument first_extremum is positive then the result sequence starts with first local maximum; if negative it starts with with local minimum; if first_extremum is zero then it doesn't matter.
>         MCO_RET mco_seq_extrema_TYPE(mco_seq_iterator_h result,
>                 mco_seq_iterator_h input,
>                 int first_extremum);

> ## Example

> Following is an example code snippet demonstrating a sequence manipulator function:

>         {
>             mco_trans_h trans;
>             mco_cursor_t quote_cursor;
>             Quote quote;
>             mco_seq_iterator_t high_iterator, low_iterator, result_iterator;
>             MCO_RET rc;
>             ...

>             for (rc = mco_cursor_first(trans, &quote_cursor);
>                 rc != MCO_S_CURSOR_END;
>                 rc = mco_cursor_next(trans, &quote_cursor))
>             {
>                 Quote_from_cursor(trans, &quote_cursor, &quote);
>                 Quote_high_iterator(&quote, &high_iterator);
>                 Quote_low_iterator(&quote, &low_iterator);
>                 ...
>                 rc = mco_seq_cross_float(&result_iterator, &low_iterator, &high_iterator);

>                 ...
>             }
>             ...
>         }