0

给定一个具有以下结构的数组(尽管其中显然包含更多项):

Array
(
    [0] => stdClass Object
        (
            [currency] => 1
            [role] => 3
            [client_company] => 
            [client_group] => 
            [hourly_rate] => 115.00
        )

    [1] => stdClass Object
        (
            [currency] => 1
            [role] => 1
            [client_company] => 
            [client_group] => 
            [hourly_rate] => 115.00
        )

    [2] => stdClass Object
        (
            [currency] => 1
            [role] => 3
            [client_company] => 58
            [client_group] => 
            [hourly_rate] => 110.00
        )
)

我正在尝试创建一个带有四个参数的函数:

  • $角色
  • $货币
  • $公司 [可选]
  • $group [可选]

(“groups”是“companies”的子级:如果指定了组,则始终也会指定母公司)

...这将返回最适合这些参数的项目的“小时费率”值,基于:

如果指定了 $row、$currency、$company 和 $group:

  • 找到与角色、货币、公司和团体相匹配的汇率。
  • 如果没有,请找到与角色、货币和公司匹配的
  • 如果没有,找一个与角色和币种匹配的
  • 如果没有,返回 FALSE

如果只指定了 $row、$currency 和 $company:

  • 找到与职位、货币和公司相匹配的费率
  • 如果没有,找一个与角色和币种匹配的
  • 如果没有,返回 FALSE

如果只指定了 $row 和 $currency:

  • 找到与角色和货币相匹配的汇率
  • 如果没有,返回 FALSE

我得到的是下面,它的工作原理。然而,它像罪恶一样丑陋。必须有一种更优雅的方式,而不是仅仅将大量 if/else 和循环放在一起。然而,现在是星期五,我午餐吃的比萨太多了,我的大脑被奶酪淹没了。

你能帮我吗?

$hourly_rate = FALSE;

if ( !empty($group) && !empty($company) ) {

    foreach ( $rates_cache as $rate ) {

        if ( $rate->currency == $currency && $rate->role == $role && (int) $rate->client_company === (int) $company && (int) $rate->client_group === (int) $group ) {
            $hourly_rate = $rate->hourly_rate;
        }

    }

    if ( empty($hourly_rate) ) {

        foreach ( $rates_cache as $rate ) {

            if ( $rate->currency == $currency && $rate->role == $role && (int) $rate->client_company === (int) $company ) {
                $hourly_rate = $rate->hourly_rate;
            }

        }
    }

    if ( empty($hourly_rate) ) {

        foreach ( $rates_cache as $rate ) {

            if ( $rate->currency == $currency && $rate->role == $role ) {
                $hourly_rate = $rate->hourly_rate;
            }

        }
    }

}else if ( !empty($company) ) {

    foreach ( $rates_cache as $rate ) {

        if ( $rate->currency == $currency && $rate->role == $role && (int) $rate->client_company === (int) $company ) {
            $hourly_rate = $rate->hourly_rate;
        }

    }

    if ( empty($hourly_rate) ) {

        foreach ( $rates_cache as $rate ) {

            if ( $rate->currency == $currency && $rate->role == $role ) {
                $hourly_rate = $rate->hourly_rate;
            }

        }
    }

}else{

    foreach ( $rates_cache as $rate ) {

        if ( $rate->currency == $currency && $rate->role == $role ) {
            $hourly_rate = $rate->hourly_rate;
        }

    }

}

return $hourly_rate;
4

1 回答 1

1

假设

我相信您cache始终采用以下格式

缓存格式:

$cache = array(
        0 => (object) (array(
                'currency' => 1,
                'role' => 3,
                'client_company' => '',
                'client_group' => '',
                'hourly_rate' => '115.00'
        )),
        1 => (object) (array(
                'currency' => 1,
                'role' => 1,
                'client_company' => '',
                'client_group' => '',
                'hourly_rate' => '115.00'
        )),
        2 => (object) (array(
                'currency' => 1,
                'role' => 3,
                'client_company' => 58,
                'client_group' => '',
                'hourly_rate' => '110.00'
        ))
);

您修改后的功能

$param = array(
        "role" => 1,
        "currency" => 1
);

echo find($cache, $param)->hourly_rate;

使用的功能

function find($cache, $param) {
    $mx = array();
    if (! isset($param['role']) || ! isset($param['currency']))
        throw new Exception("Missing Role Or Currency");
    foreach ( $cache as $k => $r ) {
        foreach ( array_keys(array_intersect($param, (array) $r)) as $key ) {
            if ($r->{$key} == $param[$key]) {
                isset($mx[$k]) ? $mx[$k] ++ : $mx[$k] = 1;
            }
        }
    }
    arsort($mx);
    return $cache[key($mx)];
}





更复杂:另一种方法

用法

$param = array(
        "role" => 1,
        "currency" => 1
);

$process = new Process($cache);
echo $process->find($param)->best()->hourly_rate; // Outputs 115.00

多个结果

当找到最合适的......有可能你会得到不止一个结果

$param = array(
        "role" => 3,
        "currency" => 1
);

$process = new Process($cache);
var_dump($process->find($param)->results());

输出

array (size=2)
  0 => 
    object(stdClass)[1]
      public 'currency' => int 1
      public 'role' => int 3
      public 'client_company' => string '' (length=0)
      public 'client_group' => string '' (length=0)
      public 'hourly_rate' => string '115.00' (length=6)
  2 => 
    object(stdClass)[3]
      public 'currency' => int 1
      public 'role' => int 3
      public 'client_company' => int 58
      public 'client_group' => string '' (length=0)
      public 'hourly_rate' => string '110.00' (length=6)

没有得到最好的结果

如果您正在寻找最便宜的奖品并且您打电话,您可以根据您的参数看到您获得 2

$param = array(
        "role" => 3,
        "currency" => 1
);

echo Process::quick($cache, $param)->best()->hourly_rate; // returns 115.00 but that is not the cheapest 

解析度

解决方案是您可以添加过滤器和 sort

$param = array(
        "role" => 3,
        "currency" => 1
);

$sort = function ($a, $b) {
    return $a->hourly_rate < $b->hourly_rate ? - 1 : 1;
};

echo Process::quick($cache, $param)->sort($sort)->best()->hourly_rate; // 110

获取所有相关信息

您也可以遍历所有结果并选择您想要插入的列以获得最佳结果

foreach ( Process::quick($cache, $param)->sort($sort)->getColoum("client_company", "hourly_rate") as $result ) {
    print_r($result);
}

输出

stdClass Object
(
    [client_company] => 58
    [hourly_rate] => 110.00
)
stdClass Object
(
    [client_company] => 
    [hourly_rate] => 115.00
)

更新类

要添加所有这些附加功能,您需要将您的课程升级到

    class Process implements JsonSerializable, IteratorAggregate {
    private $cache;
    private $matrix = array();
    private $final = array();

    function __construct($cache) {
        $this->cache = $cache;
    }

    function find($param) {
        if (! isset($param['role']) || ! isset($param['currency']))
            throw new Exception("Missing Role Or Currency");
        foreach ( $this->cache as $k => $rate ) {
            $keys = array_intersect($param, (array) $rate);
            foreach ( array_keys($keys) as $key ) {
                if ($rate->{$key} == $param[$key]) {
                    isset($this->matrix[$k]) ? $this->matrix[$k] ++ : $this->matrix[$k] = 1;
                }
            }
        }
        arsort($this->matrix);
        $this->matrix = array_keys(array_filter($this->matrix, function ($v) {
            return $v >= 2;
        }));
        $this->final = $this->sortArray($this->cache, $this->matrix);
        return $this;
    }

    public static function quick($cache, $param) {
        $process = new Process($cache);
        return $process->find($param);
    }

    public function best() {
        reset($this->final);
        return empty($this->final) ?  : current($this->final);
    }

    public function results() {
        return $this->final;
    }

    public function limit($length = 0) {
        $this->final = array_slice($this->final, 0, $length);
        return $this;
    }

    public function sort(Callable $function) {
        usort($this->final, $function);
        return $this;
    }

    public function getColoum() {
        $arg = array_flip(func_get_args());
        foreach ( $this->final as &$s ) {
            foreach ( $s as $k => $v ) {
                if (! isset($arg[$k]))
                    unset($s->{$k});
            }
        }
        return $this;
    }

    public function getIterator() {
        return new ArrayIterator($this->final);
    }

    public function jsonSerialize() {
        return json_encode($this->final);
    }

    public function __toString() {
        return $this->jsonSerialize();
    }

    private function sortArray(array $array, array $orderArray) {
        $ordered = array();
        foreach ( $orderArray as $key => $value ) {
            array_key_exists($value, $array) and $ordered[$value] = $array[$value];
        }
        return $ordered;
    }
}
于 2013-03-22T14:46:25.013 回答