Skip to content
Snippets Groups Projects
Commit 8b23c414 authored by Mactavish's avatar Mactavish
Browse files

update README for higher-order functions

parent 3016fb9b
No related branches found
No related tags found
No related merge requests found
...@@ -12,9 +12,81 @@ You will implement the following functions: ...@@ -12,9 +12,81 @@ You will implement the following functions:
* `filter`: filter a given array with a predicate function to a new array. * `filter`: filter a given array with a predicate function to a new array.
* `reduce`: "reduce" the array with a given initial accumulator and a reducer function to a final value. * `reduce`: "reduce" the array with a given initial accumulator and a reducer function to a final value.
### Map
`map` takes a pointer to the target array, the length of the target array, the size of each element in the array and a pointer to a transformer function as parameters.
It should return a pointer to a newly allocated array, in which every element will be transformed using the transformer function.
For example:
```c
int double_it(void *elem) {
*((int *)elem) *= 2;
}
int arr[] = {1, 2, 3, 4, 5};
int *new_arr = map(arr, 5, sizeof int, double_it);
// the new_arr will be {2, 4, 6, 8, 9} and the old array arr is not affected
```
### Filter
`filter` takes a pointer to the target array, the length of the target array, the size of each element in the array, a pointer to a `size_t` variable that stores the size of the filtered array and a pointer to a predicate function as parameters.
It should return a pointer to a newly allocated array which contains only those elements that fulfill the requirements posed by the predicate function.
For example:
```c
bool is_even(void *elem) {
return *((int *)elem) % 2 == 0;
}
int arr[] = {1, 2, 3, 4, 5};
size_t new_size = 0;
int *new_arr = filter(arr, 5, sizeof int, &new_size, is_even);
// the new_arr will be {2, 4} and the old array arr is not affected, new_size will be 2
```
The parameter `new_size` is necessary, otherwise there is no way of knowing the size of the filtered array since we can only deduct the size of an array only from a pointer.
### Reduce
`reduce` takes a pointer to the target array, the length of the target array, the size of each element in the array, a pointer to the initial accumulator variable and a pointer to a reducer function as parameters.
It should return a pointer to that initial accumulator.
The purpose of `reduce` is to apply a given function to a sequence of elements from left to right and reduces it to a single value using a so called accumulator.
For example:
```c
void* sum_int(void *acc, void *elem) {
int *acc_ptr = (int *)acc;
int *elem_ptr = (int *)elem;
*acc_ptr += *elem_ptr;
return acc_ptr;
}
int arr[] = {1, 2, 3, 4, 5};
int acc = 0;
int *result = reduce(arr, 5, sizeof int, &acc, sum_int);
// acc will be 1+2+3+4+5 = 15 and result actually points to acc
```
## Tips ## Tips
TBD We want the `map`, `filter` and `reduce` functions to be as generic as they can, so as you can see, the return values and the parameters of the given functions are all using `void *` pointers.
For `map` and `filter`, you will have to use `malloc` or `calloc` to allocate a new array. If the given `length` is 0, then just return a `NULL`.
In order to use the transformer/predicate/reducer function, you will have to calculate the offset of the element with the give `size`. Because you don't have information of the `type` of the array elements, so you have to calculate the offset of the elements manually.
Because we only have `void *` pointer to the elements, we can cast it into `char *` and then calculate the offset per bytes.
## Testing ## Testing
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment