Skip to content

Instantly share code, notes, and snippets.

@satheesh-chandran
Last active May 11, 2020 10:42
Show Gist options
  • Save satheesh-chandran/e623f08c0a0d648b9b44ec46aca9f03e to your computer and use it in GitHub Desktop.
Save satheesh-chandran/e623f08c0a0d648b9b44ec46aca9f03e to your computer and use it in GitHub Desktop.
Map, Filter and Reduce using function pointers in c
#include <stdlib.h>
#include "array.h"
Array* copy_array(int numbers[], int length)
{
Array* array_copy = malloc(sizeof(Array));
array_copy->array = malloc(length * sizeof(int));
for (int index = 0; index < length; index++)
{
array_copy->array[index] = numbers[index];
}
array_copy->length = length;
return array_copy;
}
Array* map(Array* src, Mapper mapper)
{
int numbers[src->length], length = 0;
for (int index = 0; index < src->length; index++)
{
numbers[index] = (*mapper)(src->array[index]);
length++;
}
return copy_array(numbers, length);
}
Array* filter(Array* src, Predicate predicate)
{
int numbers[src->length], length = 0;
for (int index = 0; index < src->length; index++)
{
if ((*predicate)(src->array[index]))
{
numbers[length] = src->array[index];
length++;
}
}
return copy_array(numbers, length);
}
int reduce(Array* src, int init, Reducer reducer)
{
int reduce_result = init;
for (int index = 0; index < src->length; index++)
{
reduce_result = (*reducer)(reduce_result, src->array[index]);
}
return reduce_result;
}
void free_array(Array* src)
{
free(src->array);
free(src);
}
#ifndef __ARRAY_H
#define __ARRAY_H
typedef enum
{
False,
True
} Bool;
typedef int (*Mapper)(int);
typedef Bool (*Predicate)(int);
typedef int (*Reducer)(int, int);
typedef struct
{
int *array;
int length;
} Array;
typedef Array *Array_ptr;
typedef int *int_ptr;
Array_ptr map(Array_ptr src, Mapper mapper);
Array_ptr filter(Array_ptr src, Predicate predicate);
int reduce(Array_ptr src, int init, Reducer reducer);
int square(int number);
Bool is_even(int number);
int add(int num1, int num2);
void print_array(Array_ptr elements);
Array_ptr copy_array(int numbers[], int length);
void free_array(Array_ptr src);
void run_test(void);
#endif
#include <stdlib.h>
#include "array_void.h"
ArrayVoid_ptr create_array_void(int length)
{
ArrayVoid_ptr array_void = malloc(sizeof(ArrayVoid));
array_void->length = 0;
array_void->array = malloc(sizeof(Object) * length);
return array_void;
}
void insert_number_to_void_array(ArrayVoid_ptr src, Object numbers, int length)
{
for (int index = 0; index < length; index++)
{
src->array[index] = (Object)(*((long int *)numbers + index));
src->length++;
}
}
ArrayVoid_ptr map_void(ArrayVoid_ptr src, MapperVoid mapper)
{
ArrayVoid_ptr map_result = create_array_void(src->length);
for (int index = 0; index < src->length; index++)
{
map_result->array[index] = mapper(src->array[index]);
map_result->length++;
}
return map_result;
}
ArrayVoid_ptr filter_void(ArrayVoid_ptr src, PredicateVoid predicate)
{
Object temp[src->length];
int count = 0;
for (int index = 0; index < src->length; index++)
{
Object current_element = src->array[index];
if (predicate(current_element))
{
temp[count] = current_element;
count++;
}
}
ArrayVoid_ptr filter_result = create_array_void(count);
for (int index = 0; index < count; index++)
{
filter_result->array[index] = temp[index];
filter_result->length++;
}
return filter_result;
}
Object reduce_void(ArrayVoid_ptr src, Object init, ReducerVoid reducer)
{
for (int index = 0; index < src->length; index++)
{
init = reducer(init, src->array[index]);
}
return init;
}
void free_void_array(ArrayVoid_ptr src)
{
free(src->array);
free(src);
}
#ifndef __ARRAY_VOID_H
#define __ARRAY_VOID_H
#include "array.h"
typedef void *Object;
typedef Object (*MapperVoid)(Object);
typedef Bool (*PredicateVoid)(Object);
typedef Object (*ReducerVoid)(Object, Object);
typedef struct
{
Object *array;
int length;
} ArrayVoid;
typedef ArrayVoid *ArrayVoid_ptr;
ArrayVoid_ptr map_void(ArrayVoid_ptr src, MapperVoid mapper);
ArrayVoid_ptr filter_void(ArrayVoid_ptr src, PredicateVoid predicate);
Object reduce_void(ArrayVoid_ptr src, Object init, ReducerVoid reducer);
void free_void_array(ArrayVoid_ptr src);
ArrayVoid_ptr create_array_void(int length);
void insert_number_to_void_array(ArrayVoid_ptr src, Object numbers, int length);
#endif
#include <stdio.h>
#include "array.h"
#include "array_void.h"
int square(int number)
{
return number * number;
}
int add(int num1, int num2)
{
return num1 + num2;
}
Bool is_even(int number)
{
return number % 2 == 0 ? True : False;
}
void print_array(Array* src)
{
for (int index = 0; index < src->length; index++)
{
printf("%d ", src->array[index]);
}
printf("\n");
}
/////////////////////////////////////////////////
Object cube(Object data)
{
long int number = (long int)data;
return (Object)(square(number) * number);
}
Object increment(Object data)
{
long int number = (int)data;
return (Object)(number + 1);
}
Object addition(Object data1, Object data2)
{
long int total = (long int)data1 + (long int)data2;
return (Object)total;
}
Bool is_odd(Object data)
{
return (int)data % 2;
}
void display_number_array(ArrayVoid_ptr array)
{
for (int index = 0; index < array->length; index++)
{
printf("%d ", (int)array->array[index]);
}
printf("\n");
}
/////////////////////////////////////////////////
int main(void)
{
int numbers[] = { 2, 6, 3, 6, 1, 9, 4, 12, 11, 3 };
int size = sizeof(numbers) / sizeof(int);
int initial = 0;
Array elements = {numbers, size};
Array *squares = map(&elements, &square);
Array* even_numbers = filter(&elements, &is_even);
printf("\nSquares of numbers is...\n");
print_array(squares);
free_array(squares);
printf("\nEven numbers is...\n");
print_array(even_numbers);
printf("\nSum of numbers is %d\n", reduce(&elements, 0, &add));
free_array(even_numbers);
run_test();
long int nums[] = {2, 6, 3, 6, 1, 9, 4, 12, 11, 3};
size = sizeof(nums) / sizeof(long int);
ArrayVoid_ptr input_array_void = create_array_void(size);
insert_number_to_void_array(input_array_void, nums, size);
ArrayVoid_ptr cubes = map_void(input_array_void, &cube);
ArrayVoid_ptr odd_numbers = filter_void(input_array_void, &is_odd);
printf("\nInput array is...\n");
display_number_array(input_array_void);
printf("\nCube of numbers...\n");
display_number_array(cubes);
printf("\nOdd numbers is...\n");
display_number_array(odd_numbers);
printf("Sum of numbers is %d\n", (int)reduce_void(input_array_void, 0, &addition));
free_void_array(cubes);
free_void_array(odd_numbers);
free_void_array(input_array_void);
return 0;
}
clean()
{
rm -rf output
rm -rf *.o
}
clean;
gcc -c *.c
gcc -o output *.o && ./output
clean;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment