【问题标题】:Is it possible to have more than one key reference the same value in PHP?PHP中是否可以有多个键引用相同的值?
【发布时间】:2018-03-15 22:52:33
【问题描述】:

我想知道是否可以稍微清理一下此代码...我有一系列汽车类别,每个键都是一个车辆代码。我将几个车辆代码映射到特定类别(例如小型、中型、大型)。我之前问过一个类似的问题,但我不确定它是否清楚,所以我简化了我的问题。 我想保持这种类似的格式,但想知道是否可以做这样的事情(这样我就不必多次写“Small”了):

        $categories = [
            'L...' => 'Luxury',
            'W...' => 'Luxury',
            'X...' => 'Specialty',

            'CB..', 'CC..', 'CD..' => 'Small' 
            // Is something like this possible to do within the $categories array ?
        ];

当前代码:

        $categories = [
            'L...' => 'Luxury',
            'W...' => 'Luxury',
            'X...' => 'Specialty',

            'CB..' => 'Small',
            'CC..' => 'Small',
            'CD..' => 'Small',
            'DB..' => 'Small',
            'DC..' => 'Small',
            'DD..' => 'Small',
            'EB..' => 'Small',
            'EC..' => 'Small',
            'ED..' => 'Small',
            'HB..' => 'Small',
            'HC..' => 'Small',
            'HD..' => 'Small',
            'MB..' => 'Small',
            'MC..' => 'Small',
            'MD..' => 'Small',
            'NB..' => 'Small',
            'NC..' => 'Small',
            'ND..' => 'Small',

            'IB..' => 'Medium',
            'IC..' => 'Medium',
            'ID..' => 'Medium',
            'JB..' => 'Medium',
            'JC..' => 'Medium',
            'JD..' => 'Medium',
            'RB..' => 'Medium',
            'RC..' => 'Medium',
            'RD..' => 'Medium',
            'SB..' => 'Medium',
            'SC..' => 'Medium',
            'SD..' => 'Medium',

            'FB..' => 'Large',
            'FC..' => 'Large',
            'FD..' => 'Large',
            'GB..' => 'Large',
            'GC..' => 'Large',
            'GD..' => 'Large',
            'PB..' => 'Large',
            'PC..' => 'Large',
            'PD..' => 'Large',
            'UB..' => 'Large',
            'UC..' => 'Large',
            'UD..' => 'Large',

            '.E..' => 'Sports', // Coupe
            '.F..' => 'SUV',
            '.G..' => 'SUV', // Crossover
            '.H..' => 'RV', // Motor Home
            '.J..' => 'Off-Road Vehicle',
            '.K..' => 'Commercial',
            '.L..' => 'Luxury', // Limousine
            '.M..' => 'Van', // Monospace
            '.N..' => 'Convertible', // Roadster
            '.P..' => 'Pickup Truck',
            '.Q..' => 'Pickup Truck',
            '.R..' => 'RV',
            '.S..' => 'Sports',
            '.T..' => 'Convertible',
            '.V..' => 'Van',
            '.W..' => 'Wagon',
            '.X..' => 'Specialty',
            '.Z..' => 'Specialty',

            '...C' => 'Electric',
            '...E' => 'Electric',
            '...H' => 'Hybrid',
            '...I' => 'Hybrid'
        ];

【问题讨论】:

  • 为什么不使用多维数组,反过来呢?例如$categories = ['Luxury' => ['L','W'], 'Specialty' => ['X'] ... and so on ... ];
  • 为什么要在代码中存储这些数据?
  • @CD001 啊,这很好 - 如果我这样做,我将如何循环每个值?
  • 完全取决于您要执行的操作,您可以使用recursive array search 来查找您所追求的项目 - 尽管您最初最好以不同的方式构造数据,在数据库或者甚至是 XML 文件,那么您就有了更多现成的功能。

标签: php arrays key refactoring code-cleanup


【解决方案1】:

你可以用array_fill_keys点赞

<?php

$aKeys = ['A','B','C'];

$aResult = array_fill_keys ( $aKeys , 'small' );

print_r($aResult);

【讨论】:

    【解决方案2】:

    根据@CD001 的评论,您可以通过反转数组并将代码存储在类别中来实现这一点,然后使用一个小函数匹配找到的并返回键/类别。

    <?php
    $categories = [
        'Luxury' => [
            'L...',
            'W...'
        ],
        'Specialty' => [
            'X...',
            '.Z..',
            '.X..'
        ],
        'Sports' => [
            '.E..',
            '.S..'
        ],
        'SUV' => [
            '.F..',
            '.G..'
        ],
        'RV' => [
            '.H..',
            '.R..'
        ],
        'Off-Road Vehicle' => [
            '.J..'
        ],
        'Commercial' => [
            '.K..'
        ],
        'Van' => [
            '.M..',
            '.V..'
        ],
        'Convertible' => [
            '.N..',
            '.T..'
        ],
        'Pickup Truck' => [
            '.P..',
            '.Q..',
        ],
        'Wagon' => [
            '.W..'
        ],
        'Electric' => [
            '...C',
            '...E'
        ],
        'Hybrid' => [
            '...H',
            '...I'
        ],
        'Small' => [
            'CB..',
            'CC..',
            'CD..',
            'DB..',
            'DC..',
            'DD..',
            'EB..',
            'EC..',
            'ED..',
            'HB..',
            'HC..',
            'HD..',
            'MB..',
            'MC..',
            'MD..',
            'NB..',
            'NC..',
            'ND..'
        ],
        'Medium' => [
            'IB..',
            'IC..',
            'ID..',
            'JB..',
            'JC..',
            'JD..',
            'RB..',
            'RC..',
            'RD..',
            'SB..',
            'SC..',
            'SD..'
        ],
        'Large' => [
            'FB..',
            'FC..',
            'FD..',
            'GB..',
            'GC..',
            'GD..',
            'PB..',
            'PC..',
            'PD..',
            'UB..',
            'UC..',
            'UD..'
        ],
    ];
    
    $getType = function($search) use ($categories) {
        foreach ($categories as $k => $v) {
            $key = array_search($search, $v);
            if ($key !== false) {
                return $k;
            }
        }
    };
    
    print_r(
        // Hybrid
        $getType('...H')
    );
    

    虽然它仍然是一个大数组,但至少你不会重复Small。您可以删除空格,如下所示:

    <?php
    $categories = [
        'Luxury' => [
            'L...', 'W...'
        ],
        'Specialty' => [
            'X...', '.Z..', '.X..'
        ],
        'Sports' => [
            '.E..', '.S..'
        ],
        'SUV' => [
            '.F..', '.G..'
        ],
        'RV' => [
            '.H..', '.R..'
        ],
        'Off-Road Vehicle' => [
            '.J..'
        ],
        ...
    

    或者把它们放在数据库中,这样会更干净。

    编辑:非常感谢@CD001

    $getType = function($search, $bestMatch = false) use ($categories) { 
        $search = str_pad($search, 4, ".", STR_PAD_RIGHT);
        $out = []; 
        foreach ($categories as $k => $v) { 
            foreach ($v as $r) { 
                if (preg_match('/' . $r . '/', $search)) { 
                    $out[] = $k; 
                }
            }
        }
    
        if ($bestMatch) {
            // work out best match by adding a count
            $out = array_count_values($out);
            // sort
            arsort($out);
            //return the best match
            $out = array_keys(array_slice($out, 0, 1))[0];
        } else {
            $out = array_values(array_unique($out));
        }
        return $out;
    };
    
    /*
    Array
    (
        [0] => Luxury
        [1] => Convertible
    )
    */
    print_r(
        $getType('LTAR')
    );
    
    //Luxury
    print_r(
        $getType('LTAR', true)
    );
    

    【讨论】:

    • 非常感谢!这真的很有帮助!我的目标是返回类别名称,所以如果车辆代码是“MCAR”,我希望它返回“Small”,因为 M 和 C 是第一个和第二个字母 ['MC...']。如果我想将 MCAR 与小类别中的 ['MC..'] 进行比较,有什么想法可以通过这种方法实现吗?再次感谢!!
    • 有趣/可能,用几个代码评论可以测试一些东西,有没有什么情况MC意味着说Medium
    • LTAR = 豪华型和敞篷版(因为 L 是第一个字母,T 是第二个字母......在某些情况下会重叠),FBAR = 大,XXXC = 电动(因为 C是最后一个字母),PQXX = 皮卡车(因为 Q 是第二个字母)..这有意义吗?
    • 由于 . 是 RegExp 中的通配符,您可以将值视为模式:在这种情况下,LTAR 将匹配 /L...//.T../ - 该函数可以返回一个类似['Luxury','Convertible'] 的数组,表示两个类别。由于我们正在使用一组非常有限的可能值,因此我们可能会侥幸成功(似乎没有任何重叠)。
    • 稍微调整一下$getType函数...$getType = function($search) use ($categories) { $out = []; foreach ($categories as $k =&gt; $v) { foreach($v as $r) { if(preg_match('/' . $r . '/', $search)) { $out[] = $k; } } } return $out; };
    【解决方案3】:

    你是否应该重新排列这个数组取决于你需要用它做什么。如果您需要根据车辆代码查找类别,您不应该更改它

    现在的方式,您可以快速高效地获得一个类别。

    $category = $categories[$vehicle_code];
    

    如果将其更改为多维结构,则此查找本质上会更慢且更复杂。有不同的方法可以做到这一点,但它需要某种版本的循环所有代码子数组,直到找到包含您的代码的那个。

    foreach ($categories as $cat => $codes) {
        if (in_array($vehicle_code, $codes)) {
            $category = $cat;
            break;
        }
    }
    

    另一方面,如果您需要显示某个类别的所有车辆代码,那么多维结构将更适合。

    如果您需要同时执行这两项操作,或者需要在车辆代码和类别之间定义关系的各种其他操作,您应该考虑将这些数据存储在数据库中。就个人而言,我认为无论如何你都应该考虑这一点。这看起来像是潜在的动态数据,如果您将其存储在您的应用程序代码中,您将在任何时候添加或更新车辆代码或类别时获得一个新版本的应用程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-27
      相关资源
      最近更新 更多