ویژگی تصویر

تابع array_uintersect_uassoc() در PHP

  /  PHP   /  تابع array_uintersect_uassoc() در PHP
بنر تبلیغاتی الف
آموزش PHP

تابع array_uintersect_uassoc() در PHP برای یافتن اشتراک بین آرایه‌ها استفاده می‌شود، با این تفاوت که برای مقایسه هم مقادیر و هم کلیدها از توابع کاربر‌تعریف (user-defined callbacks) استفاده می‌کند. این تابع زمانی مفید است که قوانین استاندارد مقایسهٔ PHP (مثل === یا ==) برای شما کافی نباشند و نیاز به منطق سفارشی داشته باشید.

امضای تابع و پارامترها

امضاarray_uintersect_uassoc(array $array1, array $array2, callable $value_compare_func, callable $key_compare_func, array ...$arrays)
پارامترها
  • $array1: آرایهٔ مرجع — کلیدها و مقادیر این آرایه در خروجی حفظ می‌شوند.
  • $array2, $arrays…: آرایه‌های دیگری که باید با $array1 مقایسه شوند.
  • $value_compare_func: تابع مقایسهٔ مقادیر. باید دو مقدار را بپذیرد و عددی منفی، صفر یا مثبت بازگرداند.
  • $key_compare_func: تابع مقایسهٔ کلیدها. باید دو کلید را بپذیرد و عددی منفی، صفر یا مثبت بازگرداند.
برگشتآرایه‌ای شامل زوج‌های کلید-مقداری از $array1 که برای هر آرایهٔ بعدی یک کلید و مقدار معادل (طبق توابع مقایسه) دارند.

قوانین توابع مقایسه (callback)

  • هر تابع مقایسه باید دو پارامتر بگیرد: اولین پارامتر از آرایهٔ اول و دومین پارامتر از آرایهٔ مقایسه‌شونده (یا بالعکس بسته به فراخوانی داخلی).
  • باید عدد 0 بازگرداند (مانند strcmp یا استفاده از مقایسه‌های عددی).
  • برای کلیدها معمولاً رشته یا عدد دریافت می‌شود، بنابراین توابعی مثل strcmp/strcasecmp یا مقایسهٔ عددی کاربردی هستند.

مثال ساده: مقایسهٔ مقدار و کلید به‌صورت حساس به حروف

 'Apple', 'Two' => 'Banana', 'three' => 'Orange'];
$array2 = ['one' => 'apple', 'TWO' => 'banana', 'four' => 'Grape'];

$value_compare = function($a, $b) {
    return strcasecmp($a, $b); // مقایسهٔ غیر حساس به حروف
};

$key_compare = function($a, $b) {
    return strcasecmp($a, $b); // مقایسهٔ غیر حساس به حروف روی کلیدها
};

$result = array_uintersect_uassoc($array1, $array2, $value_compare, $key_compare);
print_r($result);

در این مثال دو کال‌بک برای مقایسهٔ مقدار و کلید به صورت غیر حساس به بزرگ/کوچک بودن حروف تعریف شده‌اند. خروجی تابع شامل زوج‌های کلید-مقداری از $array1 خواهد بود که هم مقدار و هم کلیدشان (با ignore-case) با یکی از عناصر $array2 تطابق دارد. از آنجا که کلیدها و مقادیر هر دو با strcasecmp مقایسه می‌شوند، «One» با «one» و «Apple» با «apple» مطابقت دارد و در نتیجه آن زوج در خروجی باز می‌گردد.

مثال پیشرفته: مقایسهٔ آبجکت‌ها و کلیدهای عددی

id = $id;
        $this->name = $name;
    }
}

$array1 = [
    100 => new Item(100, 'Red'),
    101 => new Item(101, 'Blue')
];

$array2 = [
    100 => new Item(100, 'red'),
    '101' => new Item(101, 'BLUE')
];

$value_compare = function($a, $b) {
    // مقایسهٔ نام آبجکت‌ها بدون توجه به حروف
    return strcasecmp($a->name, $b->name);
};

$key_compare = function($a, $b) {
    // تبدیل به عدد و مقایسهٔ عددی
    $ia = (int)$a;
    $ib = (int)$b;
    return $ia  $ib;
};

$result = array_uintersect_uassoc($array1, $array2, $value_compare, $key_compare);
var_export($result);

در این مثال مقادیر آبجکت هستند، بنابراین در کال‌بک مقدار از ویژگی name برای مقایسه استفاده شده است. کلیدها نیز ممکن است به‌صورت رشته باشند، پس در کال‌بک کلیدها را به عدد تبدیل کرده و مقایسهٔ عددی انجام داده‌ایم. خروجی فقط زوج‌هایی از $array1 را نگه می‌دارد که هم کلیدشان (بعد از تبدیل) و هم مقدارشان مطابق یک آیتم در $array2 باشد.

نکات مهم و تله‌های متداول

  • ترتیب و کلیدهای آرایهٔ بازگشتی از $array1 گرفته می‌شود؛ به عبارتی کلیدها و مقادیر از آرایهٔ اول حفظ می‌شوند، نه از آرایه‌های بعدی.
  • توابع مقایسه باید عددی برگردانند — برگرداندن true/false رفتار صحیحی ندارد.
  • زمانی که آرایه‌ها بزرگ باشند، استفاده از کال‌بک‌های پیچیده می‌تواند هزینهٔ اجرای بالایی داشته باشد (محاسبات O(n*m)). اگر امکان دارد از توابع داخلی سریع‌تر استفاده کنید.
  • اگر فقط کلیدها یا فقط مقادیر نیاز به مقایسهٔ سفارشی داشته باشند، از توابع تخصصی‌تر مانند array_uintersect_assoc یا array_intersect_uassoc استفاده کنید تا پیچیدگی کمتر شود.
  • در نسخه‌های جدید PHP می‌توانید از closure و use برای ارسال متغیرهای محیطی به کال‌بک استفاده کنید.

بهبود و بهینه‌سازی کد

اگر مقایسات شما فقط بر پایهٔ یک فیلد خاص است (مثل نام یا id)، بهتر است ابتدا یک نمایه (index) از آرایه‌های ثانویه بسازید تا به جای مقایسهٔ هر زوج، با جستجوی سریعتر بررسی کنید. این کار زمانی که داده‌ها بزرگ هستند، قابل توجه است.

 $v) {
    $index[strtolower($v->name) . '|' . (int)$k] = true;
}

$result = [];
foreach ($array1 as $k => $v) {
    $key = strtolower($v->name) . '|' . (int)$k;
    if (isset($index[$key])) {
        $result[$k] = $v;
    }
}

در این نسخه با ساخت یک ایندکس هش، از فراخوانی‌های مکرر کال‌بک جلوگیری شده و پیچیدگی زمانی از O(n*m) به تقریباً O(n + m) کاهش می‌یابد. این روش زمانی مناسب است که منطق مقایسه ثابت و قابل تبدیل به کلید هش باشد.

خلاصه

  • array_uintersect_uassoc() برای یافتن اشتراک مبتنی بر مقایسهٔ سفارشی هم روی کلید و هم روی مقدار کاربرد دارد.
  • نیاز به دو کال‌بک دارد: یکی برای مقدار و دیگری برای کلید؛ هر دو باید عددی منفی/صفر/مثبت برگردانند.
  • برای داده‌های بزرگ یا مقایسه‌های ساده‌تر، بهتر است از ایندکس‌سازی یا توابع داخلی سریع‌تر استفاده کنید.

اگر نیاز دارید مثال اختصاصی‌تر (مثل مقایسهٔ آرایه‌هایی با ساختار خاص یا استفاده از closures پیچیده) بنویسم، آرایه‌ها و منطق مقایسهٔ مدنظر خود را ارسال کنید تا نمونهٔ منطبق و بهینه‌تری ارائه دهم.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: