# array_intersect_key

- Thread: https://externals.io/message/11389
- Original archive: https://news-web.php.net/php.internals/11389
- Started by Cristiano Duarte on 2004-07-20T19:16:20+00:00
- Messages: 10
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #11389 — Cristiano Duarte — 2004-07-20T19:16:20+00:00

URL: https://externals.io/message/11389#11389

Hi all,

I needed to intersect an array with database records indexed by the primary
key, with an array with keys and there is no php function that will do it
internally. 
The database array looks like:
$records = array ( 2587 => array('Name', 'Address', 'zip'), ...);

And the array with PKS:
$pks = array_flip(array ( 234, 897, 2587, 6788));

And the intersection would be:
$result = array_intersect_key($records, $pks);

This last action should be done 10.000 times or more, so a pure PHP
implementation takes too long, then I made the following patch to PHP-5.0.0
and PHP-4.3.8 that implements the intersection only comparing the array
keys. 

If someone would like to commit it, maybe it would be useful to other users.

Regards,

Cristiano Duarte


***********************Patch for PHP 5.0.0


--- array.c     2004-07-11 18:15:04.000000000 -0300
+++ /home/aluno/php-5.0.0-new/ext/standard/array.c      2004-07-20
13:58:47.000000000 -0300
@@ -84,6 +84,7 @@
 
 #define INTERSECT_NORMAL               0
 #define INTERSECT_ASSOC                        1
+#define INTERSECT_KEY                  2
 #define INTERSECT_COMP_DATA_INTERNAL 0
 #define INTERSECT_COMP_DATA_USER     1
 #define INTERSECT_COMP_KEY_INTERNAL  0
@@ -2797,7 +2798,8 @@
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d.
This should never happen. Please report as a bug", data_compare_type);
                        return;
                }
-       } else if (behavior == INTERSECT_ASSOC) {
+       } else if ((behavior == INTERSECT_ASSOC)
+                       ||(behavior == INTERSECT_KEY)) {
                intersect_key_compare_func = array_key_compare;
                if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL
                                &&
@@ -2910,7 +2912,7 @@
                *list = NULL;
                if (behavior == INTERSECT_NORMAL) {
                        zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
intersect_data_compare_func TSRMLS_CC);
-               } else if (behavior == INTERSECT_ASSOC) {
+               } else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY))
{
                        zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
intersect_key_compare_func TSRMLS_CC);
                }
        }
@@ -2926,7 +2928,8 @@
        
        /* go through the lists and look for common values */
        while (*ptrs[0]) {
-               if (behavior == INTERSECT_ASSOC
+               if ((behavior == INTERSECT_ASSOC
+                       || behavior == INTERSECT_KEY)
                                &&
                        key_compare_type == INTERSECT_COMP_KEY_USER) {
 
@@ -2938,11 +2941,11 @@
                                while (*ptrs[i] && (0 < (c = intersect_data_compare_func(ptrs[0],
ptrs[i] TSRMLS_CC)))) {
                                        ptrs[i]++;
                                }
-                       } else if (behavior == INTERSECT_ASSOC) {
+                       } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
                                while (*ptrs[i] && (0 < (c = intersect_key_compare_func(ptrs[0],
ptrs[i] TSRMLS_CC)))) {
                                        ptrs[i]++;
                                }
-                               if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can
compare */
+                               if ((!c && *ptrs[i]) && (behavior == INTERSECT_ASSOC)) { /* this means
that ptrs[i] is not `NULL` so we can compare */
                                        /* and "c==0" is from last operation */
                                        if (data_compare_type == INTERSECT_COMP_DATA_USER) {
                                                BG(user_compare_func_name) = args[arr_argc];
@@ -2996,7 +2999,7 @@
                                        if (0 <= intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)) {
                                                break;
                                        }
-                               } else if (behavior == INTERSECT_ASSOC) {
+                               } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
                                        /* no need of looping because indexes are unique */
                                        break;
                                }
@@ -3012,7 +3015,7 @@
                                        if (intersect_data_compare_func(ptrs[0]-1, ptrs[0] TSRMLS_CC)) {
                                                break;
                                        }
-                               } else if (behavior == INTERSECT_ASSOC) {
+                               } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
                                        /* no need of looping because indexes are unique */
                                        break;
                                }
@@ -3053,6 +3056,25 @@
 
 /* {{{ proto array array_intersect_assoc(array arr1, array arr2 [,
array ...])
    Returns the entries of arr1 that have values which are present in all
the other arguments. Keys are used to do more restrictive check */
+PHP_FUNCTION(array_intersect_key)
+{
+       php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
+                               INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_INTERNAL);
+}
+/* }}} */
+
+
+/* {{{ proto array array_uintersect_assoc(array arr1, array arr2 [,
array ...], callback data_compare_func)
+   Returns the entries of arr1 that have values which are present in all
the other arguments. Keys are used to do more restrictive check. Data is
compared by using an user-supplied callback. */
+PHP_FUNCTION(array_uintersect_key)
+{
+       php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
+                               INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_USER);
+}
+/* }}} */
+
+/* {{{ proto array array_intersect_assoc(array arr1, array arr2 [,
array ...])
+   Returns the entries of arr1 that have values which are present in all
the other arguments. Keys are used to do more restrictive check */
 PHP_FUNCTION(array_intersect_assoc)
 {
        php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_ASSOC,
--- basic_functions.c   2004-06-27 18:49:47.000000000 -0300
+++ /home/aluno/php-5.0.0-new/ext/standard/basic_functions.c    2004-07-20
14:15:00.000000000 -0300
@@ -780,6 +780,8 @@
        PHP_FE(array_unique,                                                                                                    NULL)
        PHP_FE(array_intersect,                                                                                                 NULL)
        PHP_FE(array_uintersect,                                                                                                NULL)
+       PHP_FE(array_intersect_key,                                                                                             NULL)
+       PHP_FE(array_uintersect_key,                                                                                            NULL)
        PHP_FE(array_intersect_assoc,                                                                                   NULL)
        PHP_FE(array_uintersect_assoc,                                                                                  NULL)
        PHP_FE(array_intersect_uassoc,                                                                                  NULL)
--- php_array.h 2004-01-08 15:32:51.000000000 -0200
+++ /home/aluno/php-5.0.0-new/ext/standard/php_array.h  2004-07-20
14:15:21.000000000 -0300
@@ -77,6 +77,8 @@
 PHP_FUNCTION(array_unique);
 PHP_FUNCTION(array_intersect);
 PHP_FUNCTION(array_uintersect);
+PHP_FUNCTION(array_intersect_key);
+PHP_FUNCTION(array_uintersect_key);
 PHP_FUNCTION(array_intersect_assoc);
 PHP_FUNCTION(array_uintersect_assoc);
 PHP_FUNCTION(array_intersect_uassoc);


***********************Patch for PHP 4.3.8

--- array.c     2004-04-01 16:07:01.000000000 -0300
+++ /home/aluno/php-4.3.8-new/ext/standard/array.c      2004-07-20
14:06:48.000000000 -0300
@@ -81,6 +81,7 @@
 
 #define INTERSECT_NORMAL               0
 #define INTERSECT_ASSOC                        1
+#define INTERSECT_KEY                  2
 
 PHP_MINIT_FUNCTION(array)
 {
@@ -2579,7 +2580,7 @@
                *list = NULL;
                if (behavior == INTERSECT_NORMAL) {
                        zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
array_data_compare TSRMLS_CC);
-               } else if (behavior == INTERSECT_ASSOC) {
+               } else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY))
{
                        zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
array_key_compare TSRMLS_CC);
                }
        }
@@ -2594,17 +2595,20 @@
                        if (behavior == INTERSECT_NORMAL) {
                                while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i]
TSRMLS_CC))))
                                        ptrs[i]++;
-                       } else if (behavior == INTERSECT_ASSOC) {
+                       } else if ((behavior == INTERSECT_ASSOC)
+                                       || (behavior == INTERSECT_KEY)) {
                                while (*ptrs[i] && (0 < (c = array_key_compare(ptrs[0], ptrs[i]
TSRMLS_CC))))
                                        ptrs[i]++;
-                               if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can
compare */
-                                               /* and "c==0" is from last operation */
-                                       if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
-                                               c = 1;
-                                               /* we are going to the break */
-                                       } else {
-                                               /* continue looping */
-                                       }
+                               if (behavior == INTERSECT_ASSOC) {
+                                       if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can
compare */
+                                                       /* and "c==0" is from last operation */
+                                               if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
+                                                       c = 1;
+                                                       /* we are going to the break */
+                                               } else {
+                                                       /* continue looping */
+                                               }
+                                       }
                                }
                        }
                        if (!*ptrs[i]) {
@@ -2639,7 +2643,8 @@
                                if (behavior == INTERSECT_NORMAL) {
                                        if (0 <= array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC))
                                                break;
-                               } else if (behavior == INTERSECT_ASSOC) {
+                               } else if ((behavior == INTERSECT_ASSOC)
+                                               || (behavior == INTERSECT_KEY)) {
                                        /* no need of looping because indexes are unique */
                                        break;
                                }
@@ -2653,7 +2658,8 @@
                                if (behavior == INTERSECT_NORMAL) {
                                        if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
                                                break;
-                               } else if (behavior == INTERSECT_ASSOC) {
+                               } else if ((behavior == INTERSECT_ASSOC)
+                                               || (behavior == INTERSECT_KEY)) {
                                        /* no need of looping because indexes are unique */
                                        break;
                                }
@@ -2688,6 +2694,15 @@
 /* }}} */
 
 
+/* {{{ proto array array_intersect_key(array arr1, array arr2 [,
array ...])
+   Returns the entries of arr1 that have keys which are present in all the
other arguments. */
+PHP_FUNCTION(array_intersect_key)
+{
+        php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU,
INTERSECT_KEY);
+}
+/* }}} */
+
+
 static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior)
 {
        zval ***args = NULL;
--- basic_functions.c   2004-05-24 14:02:31.000000000 -0300
+++ /home/aluno/php-4.3.8-new/ext/standard/basic_functions.c    2004-07-20
14:11:50.000000000 -0300
@@ -838,6 +838,7 @@
        PHP_FE(array_rand,                                                                                                              NULL)
        PHP_FE(array_unique,                                                                                                    NULL)
        PHP_FE(array_intersect,                                                                                                 NULL)
+       PHP_FE(array_intersect_key,                                                                                                     NULL)
        PHP_FE(array_intersect_assoc,                                                                                                   NULL)
        PHP_FE(array_diff,                                                                                                              NULL)
        PHP_FE(array_diff_assoc,                                                                                                                NULL)
--- php_array.h 2002-12-31 14:35:32.000000000 -0200
+++ /home/aluno/php-4.3.8-new/ext/standard/php_array.h  2004-07-20
14:04:38.000000000 -0300
@@ -75,6 +75,7 @@
 PHP_FUNCTION(array_rand);
 PHP_FUNCTION(array_unique);
 PHP_FUNCTION(array_intersect);
+PHP_FUNCTION(array_intersect_key);
 PHP_FUNCTION(array_intersect_assoc);
 PHP_FUNCTION(array_diff);
 PHP_FUNCTION(array_diff_assoc);

---

## #11405 — Jason Garber — 2004-07-21T00:52:47+00:00

URL: https://externals.io/message/11389#11405 · In reply to: #11389

Hello Cristiano,

  First, I'd like to say that a function of this type sounds useful.
  It's one that I've wanted for some time, particularly for verifying
  that an array has the correct keys when it is passed as a function
  parameter.
  
  If I understand what you are doing correctly, the same thing can be
  accomplished by:

     array_intersect(array_keys($records), array(234, 567, 890, 123))

  However, I agree that `array_diff_key()` and `array_intersect_key()`
  would be significantly useful functions to add to the core.

-- 
Best regards,
 Jason                            mailto:jason@ionzoft.com

Tuesday, July 20, 2004, 3:16:20 PM, you wrote:

CD> Hi all,

CD> I needed to intersect an array with database records indexed by the primary
CD> key, with an array with keys and there is no php function that will do it
CD> internally. 
CD> The database array looks like:
CD> $records = array ( 2587 => array('Name', 'Address', 'zip'), ...);

---

## #11413 — Lukas Smith — 2004-07-21T08:59:27+00:00

URL: https://externals.io/message/11389#11413 · In reply to: #11411

Andrey Hristov wrote:
> is "make test" showing problems? (i am just currious).
> I will try to review the patch later today (atm i am sick).

Which also reminds me that we still dont have a function to merge a 
multi dimensional array without messing with the array structures (which 
 `array_merge_recursive()` does if it finds any overlap).

http://bugs.php.net/bug.php?id=6911

regards,
Lukas Smith

---

## #11411 — Andrey Hristov — 2004-07-21T09:36:24+00:00

URL: https://externals.io/message/11389#11411 · In reply to: #11389

is "make test" showing problems? (i am just currious).
I will try to review the patch later today (atm i am sick).

andrey

Cristiano Duarte wrote:
> Hi all,
> 
> I needed to intersect an array with database records indexed by the primary
> key, with an array with keys and there is no php function that will do it
> internally. 
> The database array looks like:
> $records = array ( 2587 => array('Name', 'Address', 'zip'), ...);
> 
> And the array with PKS:
> $pks = array_flip(array ( 234, 897, 2587, 6788));
> 
> And the intersection would be:
> $result = array_intersect_key($records, $pks);
> 
> This last action should be done 10.000 times or more, so a pure PHP
> implementation takes too long, then I made the following patch to PHP-5.0.0
> and PHP-4.3.8 that implements the intersection only comparing the array
> keys. 
> 
> If someone would like to commit it, maybe it would be useful to other users.
> 
> Regards,
> 
> Cristiano Duarte
> 
> 
> ***********************Patch for PHP 5.0.0
> 
> 
> --- array.c     2004-07-11 18:15:04.000000000 -0300
> +++ /home/aluno/php-5.0.0-new/ext/standard/array.c      2004-07-20
> 13:58:47.000000000 -0300
> @@ -84,6 +84,7 @@
>  
>  #define INTERSECT_NORMAL               0
>  #define INTERSECT_ASSOC                        1
> +#define INTERSECT_KEY                  2
>  #define INTERSECT_COMP_DATA_INTERNAL 0
>  #define INTERSECT_COMP_DATA_USER     1
>  #define INTERSECT_COMP_KEY_INTERNAL  0
> @@ -2797,7 +2798,8 @@
>                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d.
> This should never happen. Please report as a bug", data_compare_type);
>                         return;
>                 }
> -       } else if (behavior == INTERSECT_ASSOC) {
> +       } else if ((behavior == INTERSECT_ASSOC)
> +                       ||(behavior == INTERSECT_KEY)) {
>                 intersect_key_compare_func = array_key_compare;
>                 if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL
>                                 &&
> @@ -2910,7 +2912,7 @@
>                 *list = NULL;
>                 if (behavior == INTERSECT_NORMAL) {
>                         zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
> intersect_data_compare_func TSRMLS_CC);
> -               } else if (behavior == INTERSECT_ASSOC) {
> +               } else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY))
> {
>                         zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
> intersect_key_compare_func TSRMLS_CC);
>                 }
>         }
> @@ -2926,7 +2928,8 @@
>         
>         /* go through the lists and look for common values */
>         while (*ptrs[0]) {
> -               if (behavior == INTERSECT_ASSOC
> +               if ((behavior == INTERSECT_ASSOC
> +                       || behavior == INTERSECT_KEY)
>                                 &&
>                         key_compare_type == INTERSECT_COMP_KEY_USER) {
>  
> @@ -2938,11 +2941,11 @@
>                                 while (*ptrs[i] && (0 < (c = intersect_data_compare_func(ptrs[0],
> ptrs[i] TSRMLS_CC)))) {
>                                         ptrs[i]++;
>                                 }
> -                       } else if (behavior == INTERSECT_ASSOC) {
> +                       } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
>                                 while (*ptrs[i] && (0 < (c = intersect_key_compare_func(ptrs[0],
> ptrs[i] TSRMLS_CC)))) {
>                                         ptrs[i]++;
>                                 }
> -                               if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can
> compare */
> +                               if ((!c && *ptrs[i]) && (behavior == INTERSECT_ASSOC)) { /* this means
> that ptrs[i] is not `NULL` so we can compare */
>                                         /* and "c==0" is from last operation */
>                                         if (data_compare_type == INTERSECT_COMP_DATA_USER) {
>                                                 BG(user_compare_func_name) = args[arr_argc];
> @@ -2996,7 +2999,7 @@
>                                         if (0 <= intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)) {
>                                                 break;
>                                         }
> -                               } else if (behavior == INTERSECT_ASSOC) {
> +                               } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
>                                         /* no need of looping because indexes are unique */
>                                         break;
>                                 }
> @@ -3012,7 +3015,7 @@
>                                         if (intersect_data_compare_func(ptrs[0]-1, ptrs[0] TSRMLS_CC)) {
>                                                 break;
>                                         }
> -                               } else if (behavior == INTERSECT_ASSOC) {
> +                               } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
>                                         /* no need of looping because indexes are unique */
>                                         break;
>                                 }
> @@ -3053,6 +3056,25 @@
>  
>  /* {{{ proto array array_intersect_assoc(array arr1, array arr2 [,
> array ...])
>     Returns the entries of arr1 that have values which are present in all
> the other arguments. Keys are used to do more restrictive check */
> +PHP_FUNCTION(array_intersect_key)
> +{
> +       php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
> +                               INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_INTERNAL);
> +}
> +/* }}} */
> +
> +
> +/* {{{ proto array array_uintersect_assoc(array arr1, array arr2 [,
> array ...], callback data_compare_func)
> +   Returns the entries of arr1 that have values which are present in all
> the other arguments. Keys are used to do more restrictive check. Data is
> compared by using an user-supplied callback. */
> +PHP_FUNCTION(array_uintersect_key)
> +{
> +       php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
> +                               INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_USER);
> +}
> +/* }}} */
> +
> +/* {{{ proto array array_intersect_assoc(array arr1, array arr2 [,
> array ...])
> +   Returns the entries of arr1 that have values which are present in all
> the other arguments. Keys are used to do more restrictive check */
>  PHP_FUNCTION(array_intersect_assoc)
>  {
>         php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_ASSOC,
> --- basic_functions.c   2004-06-27 18:49:47.000000000 -0300
> +++ /home/aluno/php-5.0.0-new/ext/standard/basic_functions.c    2004-07-20
> 14:15:00.000000000 -0300
> @@ -780,6 +780,8 @@
>         PHP_FE(array_unique,                                                                                                    NULL)
>         PHP_FE(array_intersect,                                                                                                 NULL)
>         PHP_FE(array_uintersect,                                                                                                NULL)
> +       PHP_FE(array_intersect_key,                                                                                             NULL)
> +       PHP_FE(array_uintersect_key,                                                                                            NULL)
>         PHP_FE(array_intersect_assoc,                                                                                   NULL)
>         PHP_FE(array_uintersect_assoc,                                                                                  NULL)
>         PHP_FE(array_intersect_uassoc,                                                                                  NULL)
> --- php_array.h 2004-01-08 15:32:51.000000000 -0200
> +++ /home/aluno/php-5.0.0-new/ext/standard/php_array.h  2004-07-20
> 14:15:21.000000000 -0300
> @@ -77,6 +77,8 @@
>  PHP_FUNCTION(array_unique);
>  PHP_FUNCTION(array_intersect);
>  PHP_FUNCTION(array_uintersect);
> +PHP_FUNCTION(array_intersect_key);
> +PHP_FUNCTION(array_uintersect_key);
>  PHP_FUNCTION(array_intersect_assoc);
>  PHP_FUNCTION(array_uintersect_assoc);
>  PHP_FUNCTION(array_intersect_uassoc);
> 
> 
> ***********************Patch for PHP 4.3.8
> 
> --- array.c     2004-04-01 16:07:01.000000000 -0300
> +++ /home/aluno/php-4.3.8-new/ext/standard/array.c      2004-07-20
> 14:06:48.000000000 -0300
> @@ -81,6 +81,7 @@
>  
>  #define INTERSECT_NORMAL               0
>  #define INTERSECT_ASSOC                        1
> +#define INTERSECT_KEY                  2
>  
>  PHP_MINIT_FUNCTION(array)
>  {
> @@ -2579,7 +2580,7 @@
>                 *list = NULL;
>                 if (behavior == INTERSECT_NORMAL) {
>                         zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
> array_data_compare TSRMLS_CC);
> -               } else if (behavior == INTERSECT_ASSOC) {
> +               } else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY))
> {
>                         zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
> array_key_compare TSRMLS_CC);
>                 }
>         }
> @@ -2594,17 +2595,20 @@
>                         if (behavior == INTERSECT_NORMAL) {
>                                 while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i]
> TSRMLS_CC))))
>                                         ptrs[i]++;
> -                       } else if (behavior == INTERSECT_ASSOC) {
> +                       } else if ((behavior == INTERSECT_ASSOC)
> +                                       || (behavior == INTERSECT_KEY)) {
>                                 while (*ptrs[i] && (0 < (c = array_key_compare(ptrs[0], ptrs[i]
> TSRMLS_CC))))
>                                         ptrs[i]++;
> -                               if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can
> compare */
> -                                               /* and "c==0" is from last operation */
> -                                       if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
> -                                               c = 1;
> -                                               /* we are going to the break */
> -                                       } else {
> -                                               /* continue looping */
> -                                       }
> +                               if (behavior == INTERSECT_ASSOC) {
> +                                       if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can
> compare */
> +                                                       /* and "c==0" is from last operation */
> +                                               if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
> +                                                       c = 1;
> +                                                       /* we are going to the break */
> +                                               } else {
> +                                                       /* continue looping */
> +                                               }
> +                                       }
>                                 }
>                         }
>                         if (!*ptrs[i]) {
> @@ -2639,7 +2643,8 @@
>                                 if (behavior == INTERSECT_NORMAL) {
>                                         if (0 <= array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC))
>                                                 break;
> -                               } else if (behavior == INTERSECT_ASSOC) {
> +                               } else if ((behavior == INTERSECT_ASSOC)
> +                                               || (behavior == INTERSECT_KEY)) {
>                                         /* no need of looping because indexes are unique */
>                                         break;
>                                 }
> @@ -2653,7 +2658,8 @@
>                                 if (behavior == INTERSECT_NORMAL) {
>                                         if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
>                                                 break;
> -                               } else if (behavior == INTERSECT_ASSOC) {
> +                               } else if ((behavior == INTERSECT_ASSOC)
> +                                               || (behavior == INTERSECT_KEY)) {
>                                         /* no need of looping because indexes are unique */
>                                         break;
>                                 }
> @@ -2688,6 +2694,15 @@
>  /* }}} */
>  
>  
> +/* {{{ proto array array_intersect_key(array arr1, array arr2 [,
> array ...])
> +   Returns the entries of arr1 that have keys which are present in all the
> other arguments. */
> +PHP_FUNCTION(array_intersect_key)
> +{
> +        php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU,
> INTERSECT_KEY);
> +}
> +/* }}} */
> +
> +
>  static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior)
>  {
>         zval ***args = NULL;
> --- basic_functions.c   2004-05-24 14:02:31.000000000 -0300
> +++ /home/aluno/php-4.3.8-new/ext/standard/basic_functions.c    2004-07-20
> 14:11:50.000000000 -0300
> @@ -838,6 +838,7 @@
>         PHP_FE(array_rand,                                                                                                              NULL)
>         PHP_FE(array_unique,                                                                                                    NULL)
>         PHP_FE(array_intersect,                                                                                                 NULL)
> +       PHP_FE(array_intersect_key,                                                                                                     NULL)
>         PHP_FE(array_intersect_assoc,                                                                                                   NULL)
>         PHP_FE(array_diff,                                                                                                              NULL)
>         PHP_FE(array_diff_assoc,                                                                                                                NULL)
> --- php_array.h 2002-12-31 14:35:32.000000000 -0200
> +++ /home/aluno/php-4.3.8-new/ext/standard/php_array.h  2004-07-20
> 14:04:38.000000000 -0300
> @@ -75,6 +75,7 @@
>  PHP_FUNCTION(array_rand);
>  PHP_FUNCTION(array_unique);
>  PHP_FUNCTION(array_intersect);
> +PHP_FUNCTION(array_intersect_key);
>  PHP_FUNCTION(array_intersect_assoc);
>  PHP_FUNCTION(array_diff);
>  PHP_FUNCTION(array_diff_assoc);

---

## #11435 — Cristiano Duarte — 2004-07-21T17:00:19+00:00

URL: https://externals.io/message/11389#11435 · In reply to: #11411

Andrey Hristov wrote:

> is "make test" showing problems? (i am just currious).
> I will try to review the patch later today (atm i am sick).
Nope. Make test shows the same errors before and after the patch.

I decided to attach the patch since it will keep tabs...

Cristiano Duarte

---

## #11437 — Cristiano Duarte — 2004-07-21T17:32:22+00:00

URL: https://externals.io/message/11389#11437 · In reply to: #11436

Andrey Hristov wrote:

>   Hallo Cristiano,
> these 2 function will be added to HEAD in few minutes. I see that the
> patch is kind of trivial and won't hurt anything :) (INTERSECT_KEY
> is just INTERSECT_ASSOC but no data comparison performed).
> I will add also `array_diff_key()` and `array_diff_ukey()`
I have added these already. :-)

Cristiano Duarte

---

## #11438 — Cristiano Duarte — 2004-07-21T17:46:25+00:00

URL: https://externals.io/message/11389#11438 · In reply to: #11436

Andrey Hristov wrote:

>   Hallo Cristiano,
> these 2 function will be added to HEAD in few minutes. I see that the
> patch is kind of trivial and won't hurt anything :) (INTERSECT_KEY
> is just INTERSECT_ASSOC but no data comparison performed).
> I will add also `array_diff_key()` and `array_diff_ukey()`
I changed the function name from array_udiff_key to array_diff_ukey.
Is this ok ? Patch attached.

Cristiano Duarte

---

## #11436 — Andrey Hristov — 2004-07-21T19:08:12+00:00

URL: https://externals.io/message/11389#11436 · In reply to: #11435

Hallo Cristiano,
these 2 function will be added to HEAD in few minutes. I see that the
patch is kind of trivial and won't hurt anything :) (INTERSECT_KEY
is just INTERSECT_ASSOC but no data comparison performed).
I will add also `array_diff_key()` and `array_diff_ukey()`

cheers,
andrey

P.S.
Andi: I think the changes are minimal, so is it possible to merge into 5_0 ?

Cristiano Duarte wrote:
> Andrey Hristov wrote:
> 
> 
> > […]
> 
> Nope. Make test shows the same errors before and after the patch.
> 
> I decided to attach the patch since it will keep tabs...
> 
> Cristiano Duarte
> 
> 
> ------------------------------------------------------------------------
> 
> --- array.c	2004-07-11 18:15:04.000000000 -0300
> +++ /home/aluno/php-5.0.0-new/ext/standard/array.c	2004-07-21 11:47:58.000000000 -0300
> @@ -77,6 +77,7 @@
>  
>  #define DIFF_NORMAL			0
>  #define DIFF_ASSOC			1
> +#define DIFF_KEY			2
>  #define DIFF_COMP_DATA_INTERNAL 0
>  #define DIFF_COMP_DATA_USER     1
>  #define DIFF_COMP_KEY_INTERNAL  0
> @@ -84,6 +85,7 @@
>  
>  #define INTERSECT_NORMAL		0
>  #define INTERSECT_ASSOC			1
> +#define INTERSECT_KEY			2
>  #define INTERSECT_COMP_DATA_INTERNAL 0
>  #define INTERSECT_COMP_DATA_USER     1
>  #define INTERSECT_COMP_KEY_INTERNAL  0
> @@ -2797,7 +2799,8 @@
>  			php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);
>  			return;
>  		}
> -	} else if (behavior == INTERSECT_ASSOC) {
> +	} else if ((behavior == INTERSECT_ASSOC)
> +			||(behavior == INTERSECT_KEY)) {
>  		intersect_key_compare_func = array_key_compare;
>  		if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL
>  				&&
> @@ -2910,7 +2913,7 @@
>  		*list = NULL;
>  		if (behavior == INTERSECT_NORMAL) {
>  			zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), intersect_data_compare_func TSRMLS_CC);
> -		} else if (behavior == INTERSECT_ASSOC) {
> +		} else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY)) {
>  			zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), intersect_key_compare_func TSRMLS_CC);
>  		}
>  	}
> @@ -2926,7 +2929,8 @@
>  	
>  	/* go through the lists and look for common values */
>  	while (*ptrs[0]) {
> -		if (behavior == INTERSECT_ASSOC
> +		if ((behavior == INTERSECT_ASSOC
> +                       || behavior == INTERSECT_KEY)
>  				&&
>  			key_compare_type == INTERSECT_COMP_KEY_USER) {
>  
> @@ -2938,11 +2942,11 @@
>  				while (*ptrs[i] && (0 < (c = intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
>  					ptrs[i]++;
>  				}
> -			} else if (behavior == INTERSECT_ASSOC) {
> +			} else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
>  				while (*ptrs[i] && (0 < (c = intersect_key_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
>  					ptrs[i]++;
>  				}
> -				if (!c && *ptrs[i]) { /* this means that ptrs[i] is not `NULL` so we can compare */
> +				if ((!c && *ptrs[i]) && (behavior == INTERSECT_ASSOC)) { /* this means that ptrs[i] is not `NULL` so we can compare */
>  					/* and "c==0" is from last operation */
>  					if (data_compare_type == INTERSECT_COMP_DATA_USER) {
>  						BG(user_compare_func_name) = args[arr_argc];
> @@ -2996,7 +3000,7 @@
>  					if (0 <= intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)) {
>  						break;
>  					}
> -				} else if (behavior == INTERSECT_ASSOC) {
> +				} else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
>  					/* no need of looping because indexes are unique */
>  					break;
>  				}
> @@ -3012,7 +3016,7 @@
>  					if (intersect_data_compare_func(ptrs[0]-1, ptrs[0] TSRMLS_CC)) {
>  						break;
>  					}
> -				} else if (behavior == INTERSECT_ASSOC) {
> +				} else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
>  					/* no need of looping because indexes are unique */
>  					break;
>  				}
> @@ -3050,7 +3054,27 @@
>  }
>  /* }}} */
>  
> +/* {{{ proto array array_intersect_key(array arr1, array arr2 [,
> +array ...])
> +    Returns the entries of arr1 that have keys which are present in all the other arguments. */
> +PHP_FUNCTION(array_intersect_key)
> +{
> +	php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
> +				INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_INTERNAL);
> +}
> +/* }}} */
> +
>  
> +/* {{{ proto array array_uintersect_key(array arr1, array arr2 [, array ...], callback data_compare_func)
> +   Returns the entries of arr1 that have keys which are present in all the other arguments. Key is compared by using an user-supplied callback. */
> +PHP_FUNCTION(array_uintersect_key)
> +{
> +	php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
> +				INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_USER);
> +}
> +/* }}} */
> +
> +   
>  /* {{{ proto array array_intersect_assoc(array arr1, array arr2 [, array ...])
>     Returns the entries of arr1 that have values which are present in all the other arguments. Keys are used to do more restrictive check */
>  PHP_FUNCTION(array_intersect_assoc)
> @@ -3151,7 +3175,8 @@
>  			php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);
>  			return;		
>  		}
> -	} else if (behavior == DIFF_ASSOC) {
> +	} else if ((behavior == DIFF_ASSOC)
> +		   		|| (behavior == DIFF_KEY)) {
>  		diff_key_compare_func = array_key_compare;
>  		if (data_compare_type == DIFF_COMP_DATA_INTERNAL 
>  				&& 
> @@ -3264,7 +3289,7 @@
>  		*list = NULL;
>  		if (behavior == DIFF_NORMAL) {
>  			zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), diff_data_compare_func TSRMLS_CC);
> -		} else if (behavior == DIFF_ASSOC) {
> +		} else if ((behavior == DIFF_ASSOC) || (behavior == DIFF_KEY)) {
>  			zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), diff_key_compare_func TSRMLS_CC);
>  		}
>  	}
> @@ -3280,7 +3305,8 @@
>  	
>  	/* go through the lists and look for values of ptr[0] that are not in the others */
>  	while (*ptrs[0]) {
> -		if (behavior == DIFF_ASSOC
> +		if ((behavior == DIFF_ASSOC
> +					|| behavior == DIFF_KEY)
>  				&&
>  			key_compare_type == DIFF_COMP_KEY_USER) {
>  			
> @@ -3292,7 +3318,7 @@
>  				while (*ptrs[i] && (0 < (c = diff_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
>  					ptrs[i]++;
>  				}
> -			} else if (behavior == DIFF_ASSOC) {
> +			} else if ((behavior == DIFF_ASSOC) || (behavior == DIFF_KEY)) {
>  				while (*ptrs[i] && (0 < (c = diff_key_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
>  					ptrs[i]++;
>  				}
> @@ -3337,7 +3363,7 @@
>  					if (diff_data_compare_func(ptrs[0] - 1, ptrs[0] TSRMLS_CC)) {
>  						break;
>  					}
> -				} else if (behavior == DIFF_ASSOC) {
> +				} else if ((behavior == DIFF_ASSOC) || (behavior == DIFF_KEY)) {
>  					/* in this case no array_key_compare is needed */
>  					break;
>  				}
> @@ -3353,7 +3379,7 @@
>  					if (diff_data_compare_func(ptrs[0]-1, ptrs[0] TSRMLS_CC)) {
>  						break;
>  					}
> -				} else if (behavior == DIFF_ASSOC) {
> +				} else if ((behavior == DIFF_ASSOC) || (behavior == DIFF_KEY)) {
>  					/* in this case no array_key_compare is needed */
>  					break;
>  				}
> @@ -3392,6 +3418,23 @@
>  }
>  /* }}} */
>  
> +/* {{{ proto array array_diff_key(array arr1, array arr2 [, array ...])
> +   Returns the entries of arr1 that have keys which are not present in any of the others arguments */
> +PHP_FUNCTION(array_diff_key)
> +{
> +	php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIFF_KEY,
> +			 DIFF_COMP_DATA_INTERNAL, DIFF_COMP_KEY_INTERNAL);
> +}
> +/* }}} */
> +
> +/* {{{ proto array array_udiff_key(array arr1, array arr2 [, array ...], callback key_comp_func)
> +   Returns the entries of arr1 that have keys which are not present in any of the others arguments. Keys are compared by user supplied function. */
> +PHP_FUNCTION(array_udiff_key)
> +{
> +	php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, DIFF_KEY,
> +			 DIFF_COMP_DATA_INTERNAL, DIFF_COMP_KEY_USER);
> +}
> +/* }}} */
>  
>  /* {{{ proto array array_diff_assoc(array arr1, array arr2 [, array ...])
>     Returns the entries of arr1 that have values which are not present in any of the others arguments but do additional checks whether the keys are equal */
> --- basic_functions.c	2004-06-27 18:49:47.000000000 -0300
> +++ /home/aluno/php-5.0.0-new/ext/standard/basic_functions.c	2004-07-21 11:36:34.000000000 -0300
> @@ -780,12 +780,16 @@
>  	PHP_FE(array_unique,													NULL)
>  	PHP_FE(array_intersect,													NULL)
>  	PHP_FE(array_uintersect,												NULL)
> +	PHP_FE(array_intersect_key,													NULL)
> +	PHP_FE(array_uintersect_key,												NULL)
>  	PHP_FE(array_intersect_assoc,											NULL)
>  	PHP_FE(array_uintersect_assoc,											NULL)
>  	PHP_FE(array_intersect_uassoc,											NULL)
>  	PHP_FE(array_uintersect_uassoc,											NULL)
>  	PHP_FE(array_diff,														NULL)
>  	PHP_FE(array_udiff,														NULL)
> +	PHP_FE(array_diff_key,												NULL)
> +	PHP_FE(array_udiff_key,												NULL)
>  	PHP_FE(array_diff_assoc,												NULL)
>  	PHP_FE(array_udiff_assoc,												NULL)
>  	PHP_FE(array_diff_uassoc,												NULL)
> --- php_array.h	2004-01-08 15:32:51.000000000 -0200
> +++ /home/aluno/php-5.0.0-new/ext/standard/php_array.h	2004-07-21 11:36:54.000000000 -0300
> @@ -77,12 +77,16 @@
>  PHP_FUNCTION(array_unique);
>  PHP_FUNCTION(array_intersect);
>  PHP_FUNCTION(array_uintersect);
> +PHP_FUNCTION(array_intersect_key);
> +PHP_FUNCTION(array_uintersect_key);
>  PHP_FUNCTION(array_intersect_assoc);
>  PHP_FUNCTION(array_uintersect_assoc);
>  PHP_FUNCTION(array_intersect_uassoc);
>  PHP_FUNCTION(array_uintersect_uassoc);
>  PHP_FUNCTION(array_diff);
>  PHP_FUNCTION(array_udiff);
> +PHP_FUNCTION(array_diff_key);
> +PHP_FUNCTION(array_udiff_key);
>  PHP_FUNCTION(array_diff_assoc);
>  PHP_FUNCTION(array_udiff_assoc);
>  PHP_FUNCTION(array_diff_uassoc);

---

## #11439 — Andrey Hristov — 2004-07-21T20:08:24+00:00

URL: https://externals.io/message/11389#11439 · In reply to: #11437

Well, i think I have found a buggie (not related to these functions and I want to
investigate it). Thus I will delay the commit.

Cristiano Duarte wrote:
> Andrey Hristov wrote:
> 
> 
> > […]
> 
> I have added these already. :-)
I see :)

andrey

---

## #11450 — Andrey Hristov — 2004-07-21T23:22:31+00:00

URL: https://externals.io/message/11389#11450 · In reply to: #11438

Cristiano Duarte wrote:
> Andrey Hristov wrote:
> 
> 
> > […]
> 
> I changed the function name from array_udiff_key to array_diff_ukey.
> Is this ok ? Patch attached.
> 
Well, my patch for `array_diff_key()` and `array_diff_ukey()` looked like yours
but when writing the regression tests I spotted a bug. I thought it is not related
to the new functions. After some testing I found the problem and it was related
to array_diff_*key(). I have placed a comment in the source at about line 3364.

cheers,
andrey
