Многомерные массивы, проверьте разницу

0

У меня есть 2 массива

Array
(
[0] => Array
    (
        [SKU] => 379
        [ProductName] => Wrap - Black
        [ProductSellingPrice] => 1.00
        [ProductQty] => 1
    )

[1] => Array
    (
        [SKU] => 3909
        [ProductName] => Wrap - Navy
        [ProductSellingPrice] => 0.00
        [ProductQty] => 1
    )

и второй:

Array
(
[0] => Array
    (
        [SKU] => 378
        [ProductName] => Wrap - White
        [ProductSellingPrice] => 1.00
        [ProductQty] => 1
    )

[1] => Array
    (
        [SKU] => 3909
        [ProductName] => Wrap - Navy
        [ProductSellingPrice] => 0.00
        [ProductQty] => 1
    )

Я хотел бы пройти через них и вернуть разницу между значениями ключа.

Теги:
arrays
loops

1 ответ

2
Лучший ответ

Я написал это некоторое время назад, чтобы сделать то, что вы просите. Метод compare_records возвращает ассоциативный массив изменений, заданных по имени поля. Каждый элемент массива представляет собой массив со следующими элементами:

  • from: original (слева) значение
  • to: новое (правое) значение
  • сообщение: сообщение журнала
  • событие: описывает природу изменения как добавление, удаление или изменение

Назовите его следующим образом:

$changes = db_tools::compare_records( $array_old, $array_new );

class db_tools
{
    public static $default_log_format = 'Field %1$s changed from "%2$s" to "%3$s"';

/**
 * Returns a sorted list of keys from two arrays
 **/
    public static function get_keys( &$a, &$b )
    {
        $keys = array();
        foreach( $a as $k => $v ) $keys[$k] = 1;
        foreach( $b as $k => $v ) $keys[$k] = 1;
        ksort( $keys );
        return array_keys( $keys );
    } // get_keys


/**
 * Compares values in two arrays and returns array of differences.
 *
 * Each  difference element is an associative array in the following format:
 *      'field/key name' => array(
 *          'from'      => "from_val"
 *        , 'to'        => "to_val"
 *        , 'message'   => "Loggable message"
 *        , 'event'     => "add" or "remove" or "change"
 *      )
 *
 * @param Array Original (old) array
 * @param Array Comparison (new) array
 * @param Array Special handling instructions -- allows you to ignore fields
 *              or truncate the logged value, as in:
 *              array(
 *                  'field_name' => 'ignore' // do not detect changes
 *                , 'field_2'    => 0 // detect changes, but do not describe them
 *                , 'field_3'    => 'from %2$s to %3s field %1$s was changed' // specially formatted log message
 *              );
 * @param Array List of keys to compare. If this is omitted, the list will be
 *              constructed from keys in the first two arguments.
 * @return Array
 * @author J.D. Pace
 * @since 2010/10/02
 **/
    public static function compare_records( &$a, &$b, $special = array(), $keyset = null )
    {
        $keys = ( empty( $keyset ) ? self::get_keys( $a, $b ) : $keyset );
        $diff = array();

        foreach( $keys as $k )
        {
            $_a = ( array_key_exists( $k, $a ) ? trim( $a[$k] ) : '' );
            $_b = ( array_key_exists( $k, $b ) ? trim( $b[$k] ) : '' );

            if( $_a != $_b )
            {
                $fmt = &self::$default_log_format;
                if( array_key_exists( $k, $special ) )
                {
                    if( $special[$k] == 'ignore' )  continue;

                    if( $special[$k] == '0' )       $fmt = '%1$s changed';
                    else                            $fmt = &$instr;

                }
                $diff[$k] = array(
                    'from'      => $_a
                  , 'to'        => $_b
                  , 'message'   => sprintf( $fmt, $k, $_a, $_b )
                  , 'event'     => (
                        empty( $_a )
                        ? 'add'
                        : (
                            empty( $_b )
                            ? 'remove'
                            : 'change'
                        )
                    )
                );
            }
        }
        return $diff;
    }

/**
 * Applies new data from record b to record a according to options keyset
 * @param Array Destination Array
 * @param Array Source Array
 * @param Array Keys to apply. If this is omitted, record b will be copied
 *              into record a
 **/
    public static function update_record( &$a, &$b, $keyset = null )
    {
        $keys = ( empty( $keyset ) ? self::get_keys( $a, $b ) : $keyset );
        $updated = array();
        foreach( $keys as $k )
        {
            $a[$k] = ( empty( $b[$k] ) ? '' : $b[$k] );
        }
    }

} // class db_tools
  • 0
    При попытке запустить это, у меня есть ошибка: trim() expects parameter 1 to be string
  • 0
    @beginningperl Этот код ожидает, что оба массива будут одномерными. Возможно ли, что элемент одного из ваших массивов - это другой массив?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню