forked from Telodendria/Cytoplasm
Apply #71: Add ArrayUnique() function.
This commit is contained in:
parent
c4121d2dba
commit
c4ef6d4ddc
2 changed files with 64 additions and 6 deletions
43
src/Array.c
43
src/Array.c
|
@ -274,6 +274,49 @@ ArraySort(Array * array, int (*compare) (void *, void *))
|
|||
ArrayQuickSort(array, 0, array->size - 1, compare);
|
||||
}
|
||||
|
||||
Array *
|
||||
ArrayUnique(Array * array, int (*compare) (void *, void *))
|
||||
{
|
||||
Array *ret;
|
||||
|
||||
size_t i;
|
||||
|
||||
if (!array)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = ArrayDuplicate(array);
|
||||
if (!ret)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ArraySize(ret) == 1)
|
||||
{
|
||||
/* There can't be any duplicates when there's only 1 value */
|
||||
return ret;
|
||||
}
|
||||
|
||||
ArraySort(ret, compare);
|
||||
|
||||
for (i = 1; i < ArraySize(ret); i++)
|
||||
{
|
||||
void *cur = ret->entries[i];
|
||||
void *prev = ret->entries[i - 1];
|
||||
|
||||
if (compare(cur, prev) == 0)
|
||||
{
|
||||
/* Remove the duplicate, and put i back where it was. */
|
||||
ArrayDelete(ret, i--);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayTrim(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Even though the following operations could be done using only the
|
||||
* public Array API defined above, I opted for low-level struct
|
||||
* manipulation because it allows much more efficient copying; we only
|
||||
|
|
|
@ -136,6 +136,21 @@ extern void * ArrayDelete(Array *, size_t);
|
|||
*/
|
||||
extern void ArraySort(Array *, int (*) (void *, void *));
|
||||
|
||||
/**
|
||||
* Remove all duplicates from an array by using the given comparison
|
||||
* function to sort the array, then remove matching values. This
|
||||
* function returns a new array with all duplicates removed. The
|
||||
* original array is unaffected. Note that arrays only store pointers
|
||||
* to values, usually values on the heap. Thus, it is possible to lose
|
||||
* pointers to duplicate values and have them leak.
|
||||
* .P
|
||||
* This is a relatively expensive operation. The array must first be
|
||||
* duplicated. Then it is sorted, then it is iterated from beginning
|
||||
* to end to remove duplicate entires. Note that the comparison
|
||||
* function is executed on each element at least twice.
|
||||
*/
|
||||
extern Array *ArrayUnique(Array *, int (*) (void *, void *));
|
||||
|
||||
/**
|
||||
* If possible, reduce the amount of memory allocated to this array
|
||||
* by calling
|
||||
|
|
Loading…
Reference in a new issue