除了switch,PHP就不能像Python一样使用Map来代替多分枝条件语句吗? (只讨论技术)...

不可否认,语言之争经常是活跃网络气氛的一把好手!今天看到一个,感觉有点意思,同时也引发了我的进一步思考。 有同学说Python么有Switch语法,Python这点不爽云云,又有同学说Python有MAP,根本就用不着switch,而PHP就不能用MAP,顺便举了一个PHP的例子。前者虽然说得对,但拿不出坑点证据,容易挑起互喷,后者反击也是不错,并且提供了一段Python和PHP对比的代码。先不论语言好坏,就技术讨论而言,我更喜欢后者,赞一个。但是,不得不指出的是,后者的PHP例子并不能支撑其论点。 所以,就后者,我给出了一个PHP的例子:

<?php
//...
$add = function(int $a, int $b){return $a+$b;};
$sub= function(int $a, int $b){return $a -$b;};
$mul = function(int $a, int $b){return $a *$b;};
$div = function(int $a, int $b){return $a / $b;};
$operations = ['+'=>$add, '-'=>$sub, '*'=>$mul,'/'=>$div];
$a=1;
$b=2;

$operator = '+';
echo $operations[$operator]($a, $b),PHP_EOL;
$operator = '-';
echo $operations[$operator]($a, $b),PHP_EOL;
$operator = '*';
echo $operations[$operator]($a, $b),PHP_EOL;
$operator = '/';
echo $operations[$operator]($a, $b),PHP_EOL;

代码写到这里,我想很明了了,PHP最常用的数据类型不是别的,就是这个万能数组。

PHP不但支持多分支语句非if/switch方式实现,而且这种用法是处理大量分支判定的利器!

可能很多PHP新手,甚至老手都习惯于 if / switch 这种语句,高级一点的,可能会用到设计模式多态什么的。但是作为一个高级PHP,必须要优先考虑这种MAP的方式,不是出于对标Python,而是出于实实在在的性能提升,以及极大代码扩展性。相信熟悉开闭原则的你,肯定不希望当新的需求过来时,用一堆if/else 或者switch case去扩展本来封闭的好好的代码,那种代码真的很low。 当然,也不是所有if/switch可以用的地方都要用map来处理,map主要用在扩展性极强,性能要求考虑上(比如,几十个可能性)等。 其实,除了这个,平时我们在做if判定的时候,还可以两者结合,性能更佳哟:

举个例子: PHP常用到数组搜索判定 我们遇到这样一个需求,从一组人的信息中,找出名字编号为31的用户信息。

<?php
//搜索
$id = 31;
//数据
$person = [ ['name'=>'zhang san','age'=>23,'no'=>31], ['name'=>'zhang san','age'=>23,'no'=>21], /*...*/ ];
//查找
$find=[];
foreach($person as $info)
{
    if($info['no'] == $id){
        $find = $info;
        break;
    }
}

发现什么问题了吗?复杂度几何?能不能把复杂度降到O(1)仔细看几遍,然后再往下看。

对的,眼尖的你肯定看出来了,这个算法的复杂度最坏O(N)是不是?如果是成千上万个数据信息呢?想想都觉得疼哈~

所以是时释放大招了,针对这种情况,一般处理就是,先优化数据结构,然后,看看我们的算法,怎样降到O(1)

当然,就原来的数据作为初始数据的话,肯定没办法优化了,我们为了优化,得这样干一遍先

//data.php 空间换时间,先处理数据

<?php
//...
$person_new = [];
foreach($person as $v)
{
    $person_new[$v['no']] = $v;    
}
unset($person);
save_json_data('data.json',$person);//存到data.json中

// search.php 使用处理后的数据

<?php
//...
$id = 31;
$person = get_json_data('data.json');
//查找
$find=[];
if(isset($person[$id])){  //亮点在这里,复杂度瞬间将为O(1) 有木有?
    $find = $person[$id];
}

好了,刚刚的例子已经举完,差不多可以收工了~其实放到Python/Java/C++或者任意其他语言中,肯定都有相应的性能优化办法,这里只是举了PHP中比较实用而且常常被各种PHPer忽略的关于数组的搜索和判定的正确用法。

最后呐,中午闲得慌,写了个C++的例子,发散发散(PS:静态语言这种表达就繁琐了一点):

#include<iostream>
#include<map>
#include<functional>
int main()
{
    std::map<std::string, std::function<double(float, float)>> opeations;
    opeations["+"] = [](const float &a, const float &b) {return  (a + b); };
    opeations["-"] = [](const float &a, const float &b) {return  (a - b); };
    opeations["*"] = [](const float &a, const float &b) {return  (a * b); };
    opeations["/"] = [](const float &a, const float &b) {return  (a / b); };

    float a = 1, b = 2;
    std::cout << opeations["+"](a, b) << "\n";
    std::cout << opeations["-"](a, b) << "\n";
    std::cout << opeations["*"](a, b) << "\n";
    std::cout << opeations["/"](a, b) << "\n";

    return 0;
}

转载于:https://my.oschina.net/lxrm/blog/708278

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值