الفرز multidim مجموعة:الأولوية إذا كان العمود يحتوي على فرعية ، ثم صدور أمر من العمود الثاني

StackOverflow https://stackoverflow.com/questions/2059255

سؤال

أنا حاليا إنشاء طريقة الفرز التي تتكون القيم من الخلية الاستعلام.

وهنا عرض موجز مجموعة:

    Array
    (
        [0] => Array
            (
                ['id'] = 1;
                ['countries'] = 'EN,CH,SP';
            )
        [1] => Array
            (
                ['id'] = 2;
                ['countries'] = 'GE,SP,SV';
            )
    )

لقد نجحت في جعل العادي usort على أساس هوية رقمية القيم ، ولكن أريد بدلا لفرز مجموعة من المحتوى من "البلدان" حقل (إذا كان يحتوي على مجموعة سلسلة كود الدولة في هذه الحالة) ، ثم من حقل معرف.

المقتطف التالي كان أول فكرة عن كيفية القيام بذلك, ولكن ليس لدي أي فكرة عن كيفية دمجها في العمل وظيفة:

in_array('EN', explode(",",$a['countries']) );

كيف يمكنك أن تفعل ذلك ؟

وذلك بفضل!


أنا حقا الحصول على أي مكان مع هذا للأسف.

هنا هو ما لدي من أجل هذه اللحظة ، إعطائي أي شيء ولكن الأخطاء: uasort() [function.uasort]: Invalid comparison function

function compare($a, $b) {
    global $usercountry;

        if ( in_array($usercountry, $a['countries']) && in_array($usercountry, $a['countries']) ) {
            $return = 0;
        }

        else if (in_array($usercountry, $a['countries'])) {
            $return = 1;
        }

        else {
            $return = -1;
        }

        return $return;


        }

        $array= usort($array, "compare");

هل هناك أي شخص يمكن أن تعطيني تلميحا من كيفية المضي قدما مع ذلك ؟

هل كانت مفيدة؟

المحلول

شخصيا, وأود أن استخدام مخصص (مجهول) وظيفة بالتزامن مع usort().

تحرير:إعادة التعليق الخاص بك.نأمل أن هذا سوف يضع لكم على المسار الصحيح.هذه الوظيفة يعطي أولوية متساوية من العناصر التي لديهما AR ولا AR, أو تعديل الأولوية عند واحد فقط لديه AR.

usort($array,function ($a, $b) {
    $ac = strpos($a['countries'],'EN');
    $bc = strpos($b['countries'],'EN');
    if (($ac !== false && $bc !== false) || ($ac == false && $bc == false)) {
        return 0;
    }
    elseif ($ac !== false) {
        return 1;
    }
    else {
        return -1;
    }
});

هذه الوظيفة ، من ناحية أخرى ، يعطي أولوية متساوية إذا كان كلا قد AR أعلى إذا كان أحد لديه EN, و لا مقارنة النص إذا لم يكن قد AR.

usort($array,function ($a, $b) {
    $ac = strpos($a['countries'],'EN');
    $bc = strpos($b['countries'],'EN');
    if ($ac !== false && $bc !== false)) {
        return 0;
    }
    elseif ($ac !== false) {
        return 1;
    }
    elseif ($bc !== false) {
        return -1;
    }
    else {
        if ($a['countries'] == $b['countries']) {
            return 0;
        }
        elseif($a['countries'] > $b['countries']) {
            return 1;
        }
        else {
            return -1;
        }
    }
});

مرة أخرى, نأمل أن هذا سوف تعطيك ما يكفي من الاتجاه إلى الأمام الخاصة بك.إذا كنت تواجه أي مشاكل لا تتردد في نشر المزيد من التعليقات و سأحاول المساعدة. ملاحظة إذا كنت ربط مقارنة خصائص متعددة مع الوزن:جرب غير تقليدي كتلة التبديل ، على سبيل المثال

$ac = array_flip(explode(',',$a['countries']));
$bc = array_flip(explode(',',$b['countries']));
switch (true) {
    case array_key_exists('EN',$ac) && !array_key_exists('EN',$bc):
        return 1;
    case array_key_exists('DE',$ac) && !array_key_exists('EN',$bc) && !array_key_exists('EN',$bc):
        return 1;
    // and so on
}

المزيد من التعديلات!

في الواقع كنت أفكر أكثر على مشكلة معقدة الفرز ، وقد تأتي مع الحل التالي, للنظر فيها.وسوف تسمح لك لتحديد العددية التصنيف على أساس الكلمات الرئيسية التي من شأنها أن تظهر في البلدان مؤشر.هنا هو رمز ، بما في ذلك على سبيل المثال:

على سبيل المثال مجموعة

$array = array(
    array(
        'countries' => 'EN,DE,SP',
    ),
    array(
        'countries' => 'EN,CH,SP',
    ),
    array(
        'countries' => 'DE,SP,CH',
    ),
    array(
        'countries' => 'DE,SV,SP',
    ),
    array(
        'countries' => 'EN,SP,FR',
    ),
    array(
        'countries' => 'DE,FR,CH',
    ),
    array(
        'countries' => 'CH,EN,SP',
    ),

);

الفرز الروتين

$rankings = array(
    'EN' => 10,
    'SP' => 8,
    'FR' => 7,
    'DE' => 5,
    'CH' => 3,
    'SV' => 1,
);
usort($array, function (&$a, &$b) use ($rankings) {
    if (isset($a['_score'])) {
        $aScore = $a['_score'];
    }
    else {
        $aScore = 0;
        $aCountries = explode(',',$a['countries']);
        foreach ($aCountries as $country) {
            if (isset($rankings[$country])) {
                $aScore += $rankings[$country];
            }
        }
        $a['_score'] = $aScore;
    }

    if (isset($b['_score'])) {
        $bScore = $b['_score'];
    }
    else {
        $bScore = 0;
        $bCountries = explode(',',$b['countries']);
        foreach ($bCountries as $country) {
            if (isset($rankings[$country])) {
                $bScore += $rankings[$country];
            }
        }
        $b['_score'] = $bScore;
    }
    if ($aScore == $bScore) {
        return 0;
    }
    elseif ($aScore > $bScore) {
        return -1;
    }
    else {
        return 1;
    }
});

ملاحظة:هذا الرمز سيتم فرز أعلى مرتبة الحرجة إلى قمة مجموعة.إذا كنت تريد عكس السلوك تغيير هذا:

    elseif ($aScore > $bScore) {

إلى

    elseif ($aScore < $bScore) {

علما أن أكبر مما تم تغييره إلى أقل من الرمز.إجراء هذا التغيير سوف يؤدي إلى أدنى مرتبة المشاركات التي يجري فرزها إلى قمة مجموعة.الأمل كل هذا يساعد!

نلاحظ أيضا!

هذا الرمز سيتم إجراء تغيير صغير إلى الصفيف الخاص بك في أنه يضيف _score عنصر إلى كل مجموعة.نأمل أن هذه ليست مشكلة ، عن طريق تخزين هذه القيمة كنت حرفيا قادرة على زيادة السرعة أكثر من ضعف (.00038-.00041 وصولا إلى .00016-.00018 في المعايير).إن لم يكن, إزالة if كتل استرداد القيمة المخزنة مؤقتا والسماح محتويات else كتل تنفيذ كل الوقت ما عدا بالطبع عن الجزء الذي يخزن قيمة النتيجة.

بالمناسبة هنا var_export() تفريغ مجموعة بعد أن تم فرز:

array (
  0 => array (
    'countries' => 'EN,SP,FR',
    '_score' => 25,
  ),
  1 => array (
    'countries' => 'EN,DE,SP',
    '_score' => 23,
  ),
  2 => array (
    'countries' => 'EN,CH,SP',
    '_score' => 21,
  ),
  3 => array (
    'countries' => 'CH,EN,SP',
    '_score' => 21,
  ),
  4 => array (
    'countries' => 'DE,SP,CH',
    '_score' => 16,
  ),
  5 => array (
    'countries' => 'DE,FR,CH',
    '_score' => 15,
  ),
  6 => array (
    'countries' => 'DE,SV,SP',
    '_score' => 14,
  ),
)

استمتع!

نصائح أخرى

وأخيرا وجدت هذه الوظيفة رائعة في PHP.net:

        function array_msort($array, $cols)
        {
            $colarr = array();
            foreach ($cols as $col => $order) {
                $colarr[$col] = array();
                foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
            }
            $eval = 'array_multisort(';
            foreach ($cols as $col => $order) {
                $eval .= '$colarr[\''.$col.'\'],'.$order.',';
            }
            $eval = substr($eval,0,-1).');';
            eval($eval);
            $ret = array();
            foreach ($colarr as $col => $arr) {
                foreach ($arr as $k => $v) {
                    $k = substr($k,1);
                    if (!isset($ret[$k])) $ret[$k] = $array[$k];
                    $ret[$k][$col] = $array[$k][$col];
                }
            }
            return $ret;

        }

وهذه هي الطريقة التي ينظر كل بلد مثل: $ مجموعة [ 'الدول'] = in_array ($ إبرة، $ كومة قش)؛                         }

$array = $array = array_msort($array, array('countries'=>SORT_DESC, 'id'=>SORT_ASC));

وبفضل جميع لمساعدتكم!

وأنت قد تنظر array_walk و <لأ href = "HTTP : //www.php.net/manual/en/function.array-walk-recursive.php "يختلط =" noreferrer نوفولو "> array_walk_recursive و <لأ href =" http://www.php.net /manual/en/function.array-map.php "يختلط =" noreferrer نوفولو "> array_map ، والتي عندما مجتمعة معا ربما للوصول الى فعل ما تريد القيام به.

وحاول مع array_mulisort .

uasort لمعرفة كيفية استخدام يحددها المستخدم مقارنة وظيفة.

أنا حاليا إنشاء طريقة الفرز التي تتكون القيم من الخلية الاستعلام.

الحقيقة:
باستخدام أي شيء آخر من الخلية إلى فرز النتائج سوف تكون أقل كفاءة (مع php ، usort() أو array_multisort() الدعوة ستكون اكثر تعقيدا وأكثر صعوبة للحفاظ على) وغير مناسب لذلك.

SQL:(Demo)

ORDER BY IF(LOCATE('EN', countries), 0, 1), id;

هذه الأولوية countries عمود القيم التي تحتوي على EN ثم أنواع على id ASC.


لمن ليس التعامل مع sql نتيجة تعيين أو لا يمكن التلاعب الاستعلام لسبب ما ، أؤيد usort().PHP7 عروض جميلة المشغل الجديد الذي يقوم بإجراء مقارنة وإرجاع واحدة من ثلاث قيم (-1, 0, 1).هذا المشغل هو بمودة يسمى "سفينة الفضاء المشغل" و يبدو مثل هذا <=>.

PHP:(Demo)

$test = [
    ['id' => 1, 'countries' => 'EN,CH,SP'],
    ['id' => 2, 'countries' => 'GE,SP,SV'],
    ['id' => 3, 'countries' => 'PR,SP,IT'],
    ['id' => 4, 'countries' => 'EN'],
    ['id' => 5, 'countries' => 'SP,EN'],
    ['id' => 6, 'countries' => 'SV,SP,EN'],
    ['id' => 7, 'countries' => 'GE,SP'],
    ['id' => 8, 'countries' => 'FR'],
    ['id' => 9, 'countries' => 'RU,EN'],
    ['id' => 10, 'countries' => 'EN,SP,IT'],
    ['id' => 11, 'countries' => 'SP,GR'],
    ['id' => 12, 'countries' => 'GR,EN']
];

usort($test, function($a, $b) {
    return [strpos($a['countries'], 'EN') === false, $a['id']] <=> [strpos($b['countries'], 'EN') === false, $b['id']];
});

var_export($test);

الإخراج:

array (
  0 => 
  array (
    'id' => 1,
    'countries' => 'EN,CH,SP',
  ),
  1 => 
  array (
    'id' => 4,
    'countries' => 'EN',
  ),
  2 => 
  array (
    'id' => 5,
    'countries' => 'SP,EN',
  ),
  3 => 
  array (
    'id' => 6,
    'countries' => 'SV,SP,EN',
  ),
  4 => 
  array (
    'id' => 9,
    'countries' => 'RU,EN',
  ),
  5 => 
  array (
    'id' => 10,
    'countries' => 'EN,SP,IT',
  ),
  6 => 
  array (
    'id' => 12,
    'countries' => 'GR,EN',
  ),
  7 => 
  array (
    'id' => 2,
    'countries' => 'GE,SP,SV',
  ),
  8 => 
  array (
    'id' => 3,
    'countries' => 'PR,SP,IT',
  ),
  9 => 
  array (
    'id' => 7,
    'countries' => 'GE,SP',
  ),
  10 => 
  array (
    'id' => 8,
    'countries' => 'FR',
  ),
  11 => 
  array (
    'id' => 11,
    'countries' => 'SP,GR',
  ),
)

مجموعة العناصر على جانبي سفينة الفضاء المشغل يتم تقييمها من اليسار إلى اليمين (leftside [0] vs rightside [0], ثم الانتقال الى زوج من [1] القيم إذا كان هناك "التعادل" بين اثنين [0] القيم).

إذا كان === false ينظر إلى الوراء ، اسمحوا لي أن أشرح...

إذا EN وجدت في البلدان سلسلة الشرط سوف تقييم false.عند مقارنة true و false, تذكر أن true ما يعادل 1 ، false يساوي 0.نريد ASC الفرز ، لذلك نحن نريد أن نضع كاذبة النتائج قبل صحيح النتائج ، ولهذا السلاسل التي تحتوي على EN تحتاج إلى return false.نأمل أن يتحسن المنطق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top