add EAPI eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first)

it compares data pointers, keeps only the first or the last of each
This commit is contained in:
Jérémy Zurcher 2013-06-12 17:08:40 +02:00
parent d3292a7ae9
commit 0d9a4e5717
3 changed files with 139 additions and 0 deletions

View File

@ -751,6 +751,64 @@ eina_list_remove_list(Eina_List *list, Eina_List *remove_list)
return return_l;
}
EAPI Eina_List *
eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first)
{
Eina_List *itr1, *itr2, *itr3;
if (!list)
return NULL;
EINA_MAGIC_CHECK_LIST(list, NULL);
if (keep_first)
{
itr1 = list;
while (itr1)
{
itr2 = itr1->next;
while (itr2)
{
itr3 = itr2->next;
if (itr1->data == itr2->data)
{
list = eina_list_remove_list(list, itr2);
}
itr2 = itr3;
}
itr1 = itr1->next;
}
}
else
{
itr1 = list->accounting->last;
while (itr1)
{
itr2 = itr1->prev;
while (itr2)
{
itr3 = itr2->prev;
if (itr1->data == itr2->data)
{
list = eina_list_remove_list(list, itr2);
}
itr2 = itr3;
}
itr1 = itr1->prev;
}
}
return list;
}
EAPI Eina_List *
eina_list_free(Eina_List *list)
{

View File

@ -619,6 +619,25 @@ EAPI Eina_List *eina_list_remove(Eina_List *list, const void *data) E
EAPI Eina_List *eina_list_remove_list(Eina_List *list, Eina_List *remove_list) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT;
/**
* @brief Remove duplicated list nodes.
*
* @param list The given linked list.
* @param keep_first Keep the first or last occurence
* @return A list pointer.
*
* This function removes multiple node occurences that have the same data.
* It keeps the first or last occurence depending of @p keep_first.
* If @p list is @c NULL, @c NULL is returned, otherwise a new list pointer
* that should be used in place of the one passed to this function.
*
* @since 1.8
*
* @warning @p list must be a pointer to the first element of the list.
*/
EAPI Eina_List *eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first) EINA_WARN_UNUSED_RESULT;
/**
* @brief Move the specified data to the head of the list.
*

View File

@ -435,6 +435,67 @@ START_TEST(eina_test_shuffle)
}
END_TEST
START_TEST(eina_test_remove_duplicates)
{
int i;
int *p;
int data[] = { 0, 1, 2, 3, 4, 5, 6 };
int result1[] = { 0, 1, 2, 3, 4, 5, 6 };
int result2[] = {2, 3, 4, 1, 6, 5, 0};
Eina_List *list = NULL;
eina_init();
list = eina_list_append(list, &data[0]);
list = eina_list_append(list, &data[1]);
list = eina_list_append(list, &data[1]);
list = eina_list_append(list, &data[2]);
list = eina_list_append(list, &data[3]);
list = eina_list_append(list, &data[4]);
list = eina_list_append(list, &data[1]);
list = eina_list_append(list, &data[5]);
list = eina_list_append(list, &data[6]);
list = eina_list_append(list, &data[5]);
list = eina_list_append(list, &data[0]);
list = eina_list_append(list, &data[0]);
fail_if(eina_list_count(list) != 12);
list = eina_list_remove_duplicates(list, EINA_TRUE);
fail_if(eina_list_count(list) != 7);
for(i = 0; i < 7; i++)
{
p = eina_list_nth(list, i);
fail_if(*p != result1[i]);
}
list = eina_list_free(list);
list = eina_list_append(list, &data[0]);
list = eina_list_append(list, &data[1]);
list = eina_list_append(list, &data[1]);
list = eina_list_append(list, &data[2]);
list = eina_list_append(list, &data[3]);
list = eina_list_append(list, &data[4]);
list = eina_list_append(list, &data[1]);
list = eina_list_append(list, &data[5]);
list = eina_list_append(list, &data[6]);
list = eina_list_append(list, &data[5]);
list = eina_list_append(list, &data[0]);
list = eina_list_append(list, &data[0]);
fail_if(eina_list_count(list) != 12);
list = eina_list_remove_duplicates(list, EINA_FALSE);
fail_if(eina_list_count(list) != 7);
for(i = 0; i < 7; i++)
{
p = eina_list_nth(list, i);
fail_if(*p != result2[i]);
}
list = eina_list_free(list);
eina_shutdown();
}
END_TEST
void
eina_test_list(TCase *tc)
{
@ -443,4 +504,5 @@ eina_test_list(TCase *tc)
tcase_add_test(tc, eina_test_sorted_insert);
tcase_add_test(tc, eina_test_list_split);
tcase_add_test(tc, eina_test_shuffle);
tcase_add_test(tc, eina_test_remove_duplicates);
}