এক অ্যারের উপাদানগুলি পিএইচপি-তে অন্য অ্যারেতে রয়েছে কিনা তা পরীক্ষা করা হচ্ছে


130

আমার পিএইচপি তে দুটি অ্যারে রয়েছে:

ব্যক্তিগণ:

Array
(
    [0] => 3
    [1] => 20
)

চেয়েছিলেন অপরাধীরা:

Array
(
    [0] => 2
    [1] => 4
    [2] => 8
    [3] => 11
    [4] => 12
    [5] => 13
    [6] => 14
    [7] => 15
    [8] => 16
    [9] => 17
    [10] => 18
    [11] => 19
    [12] => 20
)

আমি কিভাবে চেক করবেন যদি কোনো এর লোকেরা উপাদানের মধ্যে আছে চেয়েছিলেন যুদ্ধাপরাধীদের অ্যারের?

এই উদাহরণে, এটা ফেরত দিতে হবে trueকারণ 20রয়েছে ওয়ান্টেড যুদ্ধাপরাধীদের

উত্তর:


204

আপনি ব্যবহার করতে পারেন array_intersect()

$result = !empty(array_intersect($people, $criminals));

8
ভেরিয়েবল ব্যতীত অন্য কোনও কিছু দিয়ে খালি () ব্যবহার করতে পারবেন না।
গ্র্যান্টপর্পস

@grantwparks তাহলে এই ফাংশন সম্পর্কে পিএইচপি ডক্সে কেন তারা বলছেন "ভের উপস্থিত থাকলে এবং খালি, শূন্য নয় এমন মান থাকে তবে মিথ্যা ফিরিয়ে দেয় Otherwise অন্যথায় সত্য ফিরে আসে। নিম্নলিখিত বিষয়গুলি শূন্য বলে বিবেচিত হয়: অ্যারে () (একটি ফাঁকা অ্যারে) ) "? সূত্র: php.net/manual/en/function.empty.php
পেরে

5
আপনি যে পৃষ্ঠায় লিঙ্ক করেছেন: হ'ল পিএইচপি 5.5 এর পূর্বে, খালি () কেবলমাত্র ভেরিয়েবল সমর্থন করে; অন্য যে কোনও কিছুই পার্স ত্রুটির ফলস্বরূপ। অন্য কথায়, নিম্নলিখিতটি কাজ করবে না: খালি (ট্রিম ($ নাম)) পরিবর্তে, ট্রিম ব্যবহার করুন ($ নাম) == মিথ্যা ""
গ্র্যান্টপর্পস

9
মন্তব্যে উল্লিখিত হিসাবে আমি পেয়েছি যে !empty প্রত্যাশার মতো কাজ করে না । পরিবর্তে, আমি ব্যবহার করেছি count():!count(array_intersect($people, $criminals));
ম্যাটিওস 550

3
মারাত্মক ত্রুটি নিক্ষেপ করলে কেন এটি 65 টি ভোট দিয়ে উত্তর হিসাবে চিহ্নিত হয়েছে: লেখার প্রসঙ্গে ফাংশন রিটার্ন মান ব্যবহার করতে পারবেন না?
ডেভ হেক

31

অ্যারে_ইন্টারসেক্ট () এবং গণনা () খালি পরিবর্তে) ব্যবহার করে কিছুটা ভুল হয়েছে।

উদাহরণ স্বরূপ:

$bFound = (count(array_intersect($criminals, $people))) ? true : false;

2
এতে কোনও ভুল নেই তবে count()পারফরম্যান্ট হিসাবে বিবেচনা করা হয় না (যদি আপনি মাইক্রো অপ্টিমাইজেশান সম্পর্কে চিন্তা করেন তবে এটি)
জ্যাক এ স্মিথ

23

যদি 'খালি' সেরা পছন্দ না হয় তবে এ সম্পর্কে কী হবে:

if (array_intersect($people, $criminals)) {...} //when found

অথবা

if (!array_intersect($people, $criminals)) {...} //when not found

22

এই কোডটি অবৈধ কারণ আপনি কেবল ভাষা গঠনে ভেরিয়েবলগুলি পাস করতে পারেন। empty()একটি ভাষা নির্মাণ।

আপনাকে এটি দুটি লাইনে করতে হবে:

$result = array_intersect($people, $criminals);
$result = !empty($result);

সমস্যাটি নয় এটি একটি ভাষা নির্মাণ। সমস্যাটি হ'ল এটি কোনও রেফারেন্স এবং গ্রেগের একটি মান পাস করার প্রত্যাশা করে।
আর্টেফ্যাক্টো

1
@ আর্টেফ্যাক্টো, পিএইচপিএনটি থেকে "" দ্রষ্টব্য: কারণ এটি একটি ভাষা গঠন এবং কোনও ফাংশন নয়, এটি পরিবর্তনশীল ফাংশনগুলি ব্যবহার করে বলা যায় না called " এটা ঠিক পল যেমন বলেছিল।
গ্র্যান্টপর্পস

17

In_array বনাম অ্যারে_ইন্টারসেক্টের জন্য পারফরম্যান্স পরীক্ষা:

$a1 = array(2,4,8,11,12,13,14,15,16,17,18,19,20);

$a2 = array(3,20);

$intersect_times = array();
$in_array_times = array();
for($j = 0; $j < 10; $j++)
{
    /***** TEST ONE array_intersect *******/
    $t = microtime(true);
    for($i = 0; $i < 100000; $i++)
    {
        $x = array_intersect($a1,$a2);
        $x = empty($x);
    }
    $intersect_times[] = microtime(true) - $t;


    /***** TEST TWO in_array *******/
    $t2 = microtime(true);
    for($i = 0; $i < 100000; $i++)
    {
        $x = false;
        foreach($a2 as $v){
            if(in_array($v,$a1))
            {
                $x = true;
                break;
            }
        }
    }
    $in_array_times[] = microtime(true) - $t2;
}

echo '<hr><br>'.implode('<br>',$intersect_times).'<br>array_intersect avg: '.(array_sum($intersect_times) / count($intersect_times));
echo '<hr><br>'.implode('<br>',$in_array_times).'<br>in_array avg: '.(array_sum($in_array_times) / count($in_array_times));
exit;

ফলাফল এখানে:

0.26520013809204
0.15600109100342
0.15599989891052
0.15599989891052
0.1560001373291
0.1560001373291
0.15599989891052
0.15599989891052
0.15599989891052
0.1560001373291
array_intersect avg: 0.16692011356354

0.015599966049194
0.031199932098389
0.031200170516968
0.031199932098389
0.031200885772705
0.031199932098389
0.031200170516968
0.031201124191284
0.031199932098389
0.031199932098389
in_array avg: 0.029640197753906

in_array কমপক্ষে 5 গুণ দ্রুত হয়। নোট করুন যে ফলাফলটি পাওয়া মাত্রই আমরা "ব্রেক" করেছি।


মানদণ্ডের জন্য ধন্যবাদ। সুতরাং আপনি যদি জানেন যে আপনি ছোট অ্যারে পরিচালনা করছেন তবে তার সাথে থাকাই ভাল array_intersect()
টোকইন.কম

issetআরও দ্রুত। এবং আপনি সক্ষম বা অক্ষম করতে বুল ভাল ব্যবহার করতে পারেন। কী হিসাবে অনুসন্ধান মানগুলি কোনও নকল নেই তা নিশ্চিত করুন। Rayআরে_ইন্টারসেক্ট গড়: 0.52077736854553; in_array গড়: 0.015597295761108; আইসেট গড়: 0.0077081203460693´
কটটন

1

আপনি নিম্নরূপে ইন_আরে ব্যবহার করতে পারেন:

<?php
$found = null;
$people = array(3,20,2);
$criminals = array( 2, 4, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
foreach($people as $num) {
    if (in_array($num,$criminals)) {
        $found[$num] = true;
    } 
}
var_dump($found);
// array(2) { [20]=> bool(true)   [2]=> bool(true) }

অ্যারে_ইন্টারসেক্ট অবশ্যই ব্যবহার করার পক্ষে আরও সুবিধাজনক, এটি প্রমাণিত হয়েছে যে এটি কার্য সম্পাদনের দিক থেকে সত্যই সেরা নয়। আমি এই স্ক্রিপ্টটিও তৈরি করেছি:

<?php
$found = null;
$people = array(3,20,2);
$criminals = array( 2, 4, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
$fastfind = array_intersect($people,$criminals);
var_dump($fastfind);
// array(2) { [1]=> int(20)   [2]=> int(2) }

তারপরে, আমি যথাক্রমে দুটি স্নিপেট চালিয়েছি : http://3v4l.org/WGhO7/perf#tabs এবং http://3v4l.org/g1Hnu/perf#tabs এবং প্রতিটিটির কার্যকারিতা পরীক্ষা করেছি। মজার বিষয় হ'ল পিপিপি 5.6 এর জন্য মোট সিপিইউ সময়, অর্থাৎ ব্যবহারকারীর সময় + সিস্টেমের সময় একই এবং মেমরিটিও একই। পিএইচপি 5.4 এর অধীনে মোট সিপিইউ সময়টি অ্যারে_ইন্টারসেক্টের চেয়ে ইন_রেয়ের জন্য কম, যদিও সামান্য হলেও ally


ফলাফল প্রতারণা করছে। কোনও পার্থক্য পরিমাপ করার জন্য এটি কেবল একবার চালানো খুব দ্রুত। আপনার যদি প্রতি সেকেন্ডে কয়েক হাজার বা হাজার হাজার অনুরোধ থাকে তবে দ্বিতীয় সেকেন্ডের এই ভগ্নাংশগুলি দ্রুত যুক্ত হয়ে যায়, তাই আপনি যদি মনে করেন আপনার অ্যাপ্লিকেশনটি স্কেল করা দরকার, আমি in_arrayবাস্তবায়নে আটকে থাকব ।
ফ্র্যাঙ্ক ফোর্ট

1

কিছুক্ষণ গবেষণা করার পরে এটি করার একটি উপায়'s আমি একটি লারাভেল এপিআই এন্ডপয়েন্ট তৈরি করতে চেয়েছিলাম যা ক্ষেত্রটি "ব্যবহারের ক্ষেত্রে" আছে কিনা তা পরীক্ষা করে দেখায়, তাই গুরুত্বপূর্ণ তথ্যটি হল: 1) কোন ডিবি টেবিল? 2) কি ডিবি কলাম? এবং 3) সেই কলামে এমন কোনও মান আছে যা অনুসন্ধানের পদগুলির সাথে মেলে?

এটি জেনে আমরা আমাদের সহযোগী অ্যারে তৈরি করতে পারি:

$SEARCHABLE_TABLE_COLUMNS = [
    'users' => [ 'email' ],
];

তারপরে, আমরা আমাদের মানগুলি সেট করতে পারি যা আমরা যাচাই করব:

$table = 'users';
$column = 'email';
$value = 'alice@bob.com';

এর পরে, আমরা ব্যবহার করতে পারেন array_key_exists()এবং in_array()eachother সঙ্গে একটি এক, দুই ধাপ কম্বো চালানো এবং তারপর উপরে কাজ করতে truthyঅবস্থা:

// step 1: check if 'users' exists as a key in `$SEARCHABLE_TABLE_COLUMNS`
if (array_key_exists($table, $SEARCHABLE_TABLE_COLUMNS)) {

    // step 2: check if 'email' is in the array: $SEARCHABLE_TABLE_COLUMNS[$table]
    if (in_array($column, $SEARCHABLE_TABLE_COLUMNS[$table])) {

        // if table and column are allowed, return Boolean if value already exists
        // this will either return the first matching record or null
        $exists = DB::table($table)->where($column, '=', $value)->first();

        if ($exists) return response()->json([ 'in_use' => true ], 200);
        return response()->json([ 'in_use' => false ], 200);
    }

    // if $column isn't in $SEARCHABLE_TABLE_COLUMNS[$table],
    // then we need to tell the user we can't proceed with their request
    return response()->json([ 'error' => 'Illegal column name: '.$column ], 400);
}

// if $table isn't a key in $SEARCHABLE_TABLE_COLUMNS,
// then we need to tell the user we can't proceed with their request
return response()->json([ 'error' => 'Illegal table name: '.$table ], 400);

আমি লারাভেল-নির্দিষ্ট পিএইচপি কোডের জন্য ক্ষমা চাইছি, তবে আমি এটি ছেড়ে দেব কারণ আমি মনে করি আপনি এটি ছদ্ম কোড হিসাবে পড়তে পারেন। গুরুত্বপূর্ণ অংশটি হ'ল দুটি ifবিবৃতি যা সুসংগতভাবে কার্যকর করা হয়।

array_key_exists()এবং in_array()পিএইচপি ফাংশন হয়।

উৎস:

অ্যালগরিদম যে আমি উপরে দেখিয়েছেন সম্পর্কে চমৎকার ব্যাপার হল আপনি যেমন বিশ্রাম শেষবিন্দু করতে পারে GET /in-use/{table}/{column}/{value}(যেখানে table, columnএবংvalue ভেরিয়েবল)।

আপনি থাকতে পারে:

$SEARCHABLE_TABLE_COLUMNS = [
    'accounts' => [ 'account_name', 'phone', 'business_email' ],
    'users' => [ 'email' ],
];

এবং তারপরে আপনি জিইটি অনুরোধগুলি যেমন করতে পারেন:

GET /in-use/accounts/account_name/Bob's Drywall (আপনার শেষ অংশটি ইউরির প্রয়োজন হতে পারে তবে সাধারণত তা হয় না)

GET /in-use/accounts/phone/888-555-1337

GET /in-use/users/email/alice@bob.com

এটাও লক্ষ করুন যে কেউ না করতে পারে:

GET /in-use/users/password/dogmeat1337কারণ passwordআপনার অনুমোদিত কলামগুলির তালিকায় তালিকাভুক্ত নয় user

তোমার ভ্রমনে ভাগ্য সুপ্রসন্ন হোক।


এই প্রশ্নের সাথে কী করতে হবে তা আমার কোনও ধারণা নেই তবে আমি একবার দেখেছিলাম এবং: আমি সত্যিই আশা করি আপনি গতিশীল ডেটা কখনও ব্যবহার করবেন না $SEARCHABLE_TABLE_COLUMNS! এটি কোনও ইঞ্জেকশনের জন্য চিৎকার করে - এটির মধ্যে কোনও "অতি সুরক্ষিত ফ্রেমওয়ার্ক ক্যোয়ারী বিল্ডার" নেই যা সেই মুখোশের চেষ্টা করে এবং ফিল্টার টেবিল এবং কলাম স্ট্রিংয়ের চেষ্টা করে! শেষে টেবিল এবং কলামের স্ট্রিংগুলি স্থানধারক (প্রস্তুত বিবৃতি) এর মাধ্যমে যুক্ত করা যাবে না এবং অবশ্যই সরাসরি এর মতো sertedোকাতে হবে SELECT ... FROM {$table} WHERE {$column} = :placeholder ....। অফসি অ্যাডাপ্টারের উপর নির্ভর করে (মাইএসকিএল, মঙ্গো, ...) তবে এটি সংরক্ষণ করার কোনও যুক্তি নয়! Pls স্থির বা কোনও তালিকা নেই =)
কটটন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.