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
        )
)

4つのパラメーターを受け取る関数を作成しようとしています。

  • $ role
  • $currency
  • $company[オプション]
  • $group[オプション]

(「グループ」は「会社」の子です。グループが指定されている場合、親会社も常に指定されます)

...そして、次のことに基づいて、これらのパラメータに最適なアイテムから「時給」の値を返します。

$ 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 に答える