php foreach组的结果由3组字符组成

php foreach组的结果由3组字符组成

问题描述:

I am trying to group some foreach results based on the first 3 sets of characters.

For example i am currently listing sku codes for products and they look like this:

REF-MUSBOM-0500-ORA
REF-PROCOF-0001-LAT
REF-WHEREF-0001-TRO
REF-WHEREF-0001-ORA
REF-SHAKER-0700-C/B
REF-CREMON-0100-N/A
REF-GLUSUL-0090-N/A
REF-CRECAP-0090-N/A
REF-ALBFER-0120-N/A
REF-TSHCOT-LARG-BLK
REF-TSHCOT-MEDI-BLK
REF-ALBMAG-0090-N/A
REF-GYMJUG-2200-N/A
REF-OMEGA3-0090-N/A
REF-NEXGEN-0060-N/A
REF-VITAD3-0100-N/A
REF-SSSHAK-0739-N/A
REF-GINKGO-0090-N/A
REF-DIGEZY-0090-N/A
REF-VEST00-MEDI-N/A
REF-VEST00-LARG-N/A
REF-CREMON-0250-N/A
REF-MSM----0250-N/A
REF-GRNTEA-0100-N/A
REF-COLOST-0100-N/A
REF-GLUCHO-0090-N/A
REF-ZINCMA-0100-N/A
REF-BETALA-0250-N/A
REF-DRIBOS-0250-N/A
REF-HMB000-0090-N/A
REF-ALACID-0090-N/A
REF-CLA000-0090-N/A
REF-ACETYL-0090-N/A
REF-NXGPRO-0090-N/A
REF-LGLUTA-0250-N/A
REF-BCAA20-0200-N/A
REF-FLAPJA-0012-ACR
REF-FLAPJA-0012-MAP
REF-LCARNI-0100-N/A
REF-CORDYC-0090-N/A
REF-CREMON-0500-N/A
REF-BCAAEN-0330-APP
REF-PREWKT-0300-FPU
REF-TESFUS-0090-N/A
REF-AMIIFUS-0300-GAP
REF-AMIIFUS-0300-WME
REF-BCAINT-0400-FPU
REF-KRILLO-0090-N/A
REF-AMIIFUS-0300-PLE
REF-AMIIFUS-0300-FPU
REF-BCAINT-0400-WME
REF-ENZQ10-0090-N/A
REF-THERMO-0100-N/A
REF-LGLUTA-0500-N/A
REF-RBAR00-0012-DCB
REF-RBAR00-0012-PBC
REF-RBAR00-0012-WCR
REF-IMHEAV-2200-CHO
REF-PROCOF-0012-N/A
REF-DIEPRO-0900-STR
REF-DIEPRO-0900-BOF
REF-DIEPRO-0900-CHO
REF-INWPRO-0900-VAN
REF-INWPRO-0900-BOF
REF-INWPRO-0900-BCS
REF-INWPRO-0900-CHO
REF-INWPRO-0900-CMI
REF-INWPRO-0900-RAS
REF-INWPRO-0900-STR
REF-INWPRO-0900-CIN
REF-INWPRO-0900-CPB
REF-EGGPRO-0900-CHO
REF-EGGPRO-0900-VAN
REF-MICCAS-0909-CHO
REF-MICCAS-0909-CMI
REF-MICCAS-0909-VAN
REF-MICCAS-0909-STR
REF-BCAA50-0500-N/A
REF-MICWHE-0909-STR
REF-MICWHE-0909-VAN
REF-MICWHE-0909-CHIO
REF-MICWHE-0909-BAN
REF-1STOXT-2030-STR
REF-1STOXT-2030-VAN
REF-1STOXT-2030-CHO
REF-MUSBOM-0600-BCH
REF-MUSBOM-0600-FPU
REF-MUSBCF-0600-BCH
REF-MUSBCF-0600-FPU
REF-VEGANP-2100-STR
REF-VEGANP-2100-CHO
REF-INMPRO-2270-CPB
REF-DIETMR-2400-CPB
REF-INMPRO-2270-SCR
REF-INMPRO-2270-VIC
REF-MATRIX-1800-FRU
REF-INMPRO-2270-BOF
REF-MATRIX-1800-CHO
REF-INMPRO-2270-CHO
REF-ONESTO-2100-CHO

In the above list there are 2 skus which are:

REF-WHEREF-0001-TRO
REF-WHEREF-0001-ORA

The first 3 sets of characters split by - are the same. What would be the best approach of grouping all results leaving me an array something like this:

Array
(
[REF-WHEREF-0001] => Array
    (
        [0] => REF-WHEREF-0001-TRO
        [1] => REF-WHEREF-0001-ORA

    )
)

Are the first 3 groups (excluding the multiple -) always 13 characters? Then do something like this:

<?php
$arr = ["REF-MUSBOM-0500-ORA",
    "REF-PROCOF-0001-LAT",
    "REF-WHEREF-0001-TRO",
    "REF-WHEREF-0001-PPL"];

$resultArr = [];
foreach ($arr as $sku) {
    $resultArr[substr($sku, 0, 15)][] = $sku;
}

var_dump($resultArr);

If that length varies you might want to work with a regex or the strpos() of the third -.

I must say that I think you could come up with this yourself, since you were already thinking in the right direction i.e. foreach()

EDIT: Because I found other solutions more elegant looking, I decided to compare efficiency. This solution is a lot faster than the other ones.

You will need to pick a group with some basics use of explode, implode and str_replace.

What does this solution do.

  1. loop through the array of your items
  2. explode to get last item index of exploded string assuming that it would be dynamic in the end
  3. implode & str_replace again to find out string of group name
  4. And last strpos & in_array to have sample reponse

Solution

$array = array(
    'REF-MUSBOM-0500-ORA',
    'REF-PROCOF-0001-LAT',
    'REF-WHEREF-0001-TRO',
    'REF-WHEREF-0001-ORA',
    'REF-SHAKER-0700-C/B',
    'REF-CREMON-0100-N/A',
    'REF-GLUSUL-0090-N/A',
    'REF-CRECAP-0090-N/A',
    'REF-ALBFER-0120-N/A',
);

$new_array = array();
foreach ($array as $key => $val) {
    $group_arr = explode('-', $val);
    $end = end($group_arr);
    $combined_group = implode('-', $group_arr);
    $group = str_replace('-' . $end, '', $combined_group);

    if (strpos($val, $group) !== false && !in_array($group, $new_array)) {
        $new_array[$group][] = $val;
    }
}
echo '<pre>';print_r($new_array);echo '</pre>';

See demo on Sandbox

I always create a new array with the index that I need for group, try this:

    $arr=array('REF-MUSBOM-0500-ORA',
'REF-PROCOF-0001-LAT',
'REF-WHEREF-0001-TRO');
$newarr=array();
foreach($arr as $a){
    $b=explode('-',$a);
    array_pop($b);
    $b=implode("-", $b);
    $newarr[$b][]=$a;
}
echo '<pre>',print_r($newarr),'</pre>';