代码之家  ›  专栏  ›  技术社区  ›  Tendi

如何将大量条件浓缩成查找数组?

  •  1
  • Tendi  · 技术社区  · 8 年前

    我正在尝试编写一个函数 $InterestRate 汽车保险费的价值。我在代码下面插入了表格:

    目前我已尝试:

    function interestRate() {
    if ((int)$VehicleYear >= 2001) && (int)$VehicleYear <= 2005){
    
        $Term = 24;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 15.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 19.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 22.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 22.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 22.90;
        }
    }
    
    if ((int)$VehicleYear == 2006){
    
        $Term = 24;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 15.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 18.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 21.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 22.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 22.90;
        }
    }
    if ((int)$VehicleYear == 2007){
    
        $Term = 36;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 15.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 18.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 21.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 22.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 22.90;
        }
    }
    if ((int)$VehicleYear == 2008){
    
        $Term = 36;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 14.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 17.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 21.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 21.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 21.90;
        }
    }
    
    if ((int)$VehicleYear == 2009){
    
        $Term = 36;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 14.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 17.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 20.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 20.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 20.90;
        }
    }
    
    if ((int)$VehicleYear == 2010){
    
        $Term = 36;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 14.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 17.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 20.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 20.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 20.90;
        }
    }
    
    if ((int)$VehicleYear == 2011){
    
        $Term = 42;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 14.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 16.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 19.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 19.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 20.90;
        }
    }
    
    if ((int)$VehicleYear == 2012){
    
        $Term = 42;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 12.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 15.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 18.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 19.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 19.90;
        }
    }
    
    if ((int)$VehicleYear == 2013){
    
        $Term = 42;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 12.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 15.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 18.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 18.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 18.90;
        }
    }
    
    if ((int)$VehicleYear >= 2014){
    
        $Term = 48;
    
        if ((int)$CreditScore >= 720){
            $InterestRate = 11.90;
        }
        elseif ((int)$CreditScore >= 610) || ((int)$CreditScore <= 719) {
            $InterestRate = 14.90;
        }
        elseif ((int)$CreditScore >= 580) || ((int)$CreditScore <= 609) {
            $InterestRate = 17.90;
        }
        elseif ((int)$CreditScore >= 530) || ((int)$CreditScore <= 579) {
            $InterestRate = 18.90;
        }
        elseif ((int)$CreditScore >= 489) || ((int)$CreditScore <= 529) {
            $InterestRate = 18.90;
        }
    }
    }
    

    当我尝试使用时,它既乏味又根本不起作用 美元利率 在计算中。解决这个问题的最佳方法是什么?

    编辑 :有些人提到使用SQL表。我不知道该怎么做。但这基本上是我的桌子

    <table style="undefined;table-layout: fixed; width: 497px">
    <colgroup>
    <col style="width: 93px">
    <col style="width: 73px">
    <col style="width: 75px">
    <col style="width: 64px">
    <col style="width: 64px">
    <col style="width: 64px">
    <col style="width: 64px">
    </colgroup>
      <tr>
        <th>Vehicle Year</th>
        <th>Term</th>
        <th>FICO</th>
        <th>FICO</th>
        <th>FICO</th>
        <th>FICO</th>
        <th>FICO</th>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td>720 +</td>
        <td>719-610</td>
        <td>609-580</td>
        <td>579-530</td>
        <td>529-489</td>
      </tr>
      <tr>
        <td>2014-current</td>
        <td>48</td>
        <td>11</td>
        <td>14</td>
        <td>17</td>
        <td>18</td>
        <td>18</td>
      </tr>
      <tr>
        <td>2013</td>
        <td>42</td>
        <td>12</td>
        <td>15</td>
        <td>18</td>
        <td>18</td>
        <td>18</td>
      </tr>
      <tr>
        <td>2012</td>
        <td>42</td>
        <td>12</td>
        <td>15</td>
        <td>18</td>
        <td>19</td>
        <td>19</td>
      </tr>
      <tr>
        <td>2011</td>
        <td>42</td>
        <td>14</td>
        <td>16</td>
        <td>19</td>
        <td>19</td>
        <td>20</td>
      </tr>
      <tr>
        <td>2010</td>
        <td>36</td>
        <td>14</td>
        <td>17</td>
        <td>20</td>
        <td>20</td>
        <td>20</td>
      </tr>
      <tr>
        <td>2009</td>
        <td>36</td>
        <td>14</td>
        <td>17</td>
        <td>20</td>
        <td>20</td>
        <td>20</td>
      </tr>
      <tr>
        <td>2008</td>
        <td>36</td>
        <td>14</td>
        <td>17</td>
        <td>21</td>
        <td>21</td>
        <td>21</td>
      </tr>
      <tr>
        <td>2007</td>
        <td>36</td>
        <td>15</td>
        <td>18</td>
        <td>21</td>
        <td>22</td>
        <td>21</td>
      </tr>
      <tr>
        <td>2006</td>
        <td>24</td>
        <td>15</td>
        <td>18</td>
        <td>21</td>
        <td>22</td>
        <td>22</td>
      </tr>
      <tr>
        <td>2001-2005</td>
        <td>24</td>
        <td>15</td>
        <td>19</td>
        <td>22</td>
        <td>22</td>
        <td>22</td>
      </tr>
    </table>
    Extra o
    2 回复  |  直到 3 年前
        1
  •  1
  •   Kenney    8 年前

    现在开始:删除所有重复代码:

    function creditScore( $cs ) {
        $cs = (int) $cs;
    
        if     ($cs >= 720)               return 5;
        elseif ($cs >= 610 && $cs <= 719) return 4;
        elseif ($cs >= 580 && $cs <= 609) return 3;
        elseif ($cs >= 530 && $cs <= 579) return 2;
        elseif ($cs >= 489 && $cs <= 529) return 1;
        else                              return 0;
    }
    
    function interestRate($vehicleYear, $creditScore) {
        $vehicleYear = (int) $vehicleYear;
        $cred = creditScore( $creditScore );
        if ( ! $cred )      // handle credit score below 489: returns 0
            throw new Exception("Unsupported creditScore: $creditScore" );
        $cred--;    // otherwise it's 1..5, change to 0..4 for array index
    
        $rates = [
            2001 => [ 'term' => 24, 'rates' => [ 22.90, 22.90, 22.90, 19.90, 15.90 ] ],
            2002 => [ 'term' => 24, 'rates' => [ 22.90, 22.90, 22.90, 19.90, 15.90 ] ],
            2003 => [ 'term' => 24, 'rates' => [ 22.90, 22.90, 22.90, 19.90, 15.90 ] ],
            2004 => [ 'term' => 24, 'rates' => [ 22.90, 22.90, 22.90, 19.90, 15.90 ] ],
            2005 => [ 'term' => 24, 'rates' => [ 22.90, 22.90, 22.90, 19.90, 15.90 ] ],
            2006 => [ 'term' => 24, 'rates' => [ 22.90, 22.90, 21.90, 18.90, 15.90 ] ],
            2007 => [ 'term' => 36, 'rates' => [ 22.90, 22.90, 21.90, 18.90, 15.90 ] ],
            2008 => [ 'term' => 36, 'rates' => [ 22.90, 22.90, 21.90, 17.90, 14.90 ] ],
            2009 => [ 'term' => 36, 'rates' => [ 20.90, 20.90, 20.90, 17.90, 14.90 ] ],
            2010 => [ 'term' => 36, 'rates' => [ 20.90, 20.90, 20.90, 17.90, 14.90 ] ],
            2011 => [ 'term' => 42, 'rates' => [ 20.90, 19.90, 19.90, 16.90, 14.90 ] ],
            2012 => [ 'term' => 42, 'rates' => [ 19.90, 19.90, 18.90, 15.90, 12.90 ] ],
            2013 => [ 'term' => 42, 'rates' => [ 18.90, 18.90, 18.90, 15.90, 12.90 ] ],
            2014 => [ 'term' => 48, 'rates' => [ 18.90, 18.90, 17.90, 14.90, 11.90 ] ],
        ];
    
        return [ // TODO: check if isset( $rates[$vehicleYear ])
            $rates[$vehicleYear]['rates'][ $cred ],
            $rates[$vehicleYear]['term']
        ];
    }
    
    list( $interestRate, $term ) = interestRate( 2013, 666 );
    
        2
  •  0
  •   mickmackusa    3 年前

    我喜欢一些,但不是所有肯尼的答案。我查找速率数组是一个好主意,但它应该只声明一次,而不是每次调用函数时都声明一次。电池短路 if s确定信用评分指数是好的,但第二个条件是( <= )在逻辑上是不必要的。

    我建议将查找数组定义为常量,以便它只声明一次,并具有全局范围。这是完全合适的,因为查找表中的金额在处理过程中不应更改。

    当正确设计查找数组时,维护/扩展应该只涉及调整查找数组,而不涉及处理代码。

    这使得您的php代码只需一步就可以传输到数据库表中,以防您的应用程序发现对数据维护或扩展的需求增加。

    代码:( Demo )

    define(
        'TERM_RATES_BY_YEAR',
        [
            2001 => ['term' => 24, 'rates' => [15.90, 19.90, 22.90, 22.90, 22.90]],
            2002 => ['term' => 24, 'rates' => [15.90, 19.90, 22.90, 22.90, 22.90]],
            2003 => ['term' => 24, 'rates' => [15.90, 19.90, 22.90, 22.90, 22.90]],
            2004 => ['term' => 24, 'rates' => [15.90, 19.90, 22.90, 22.90, 22.90]],
            2005 => ['term' => 24, 'rates' => [15.90, 19.90, 22.90, 22.90, 22.90]],
            2006 => ['term' => 24, 'rates' => [15.90, 18.90, 21.90, 22.90, 22.90]],
            2007 => ['term' => 36, 'rates' => [15.90, 18.90, 21.90, 22.90, 22.90]],
            2008 => ['term' => 36, 'rates' => [14.90, 17.90, 21.90, 22.90, 22.90]],
            2009 => ['term' => 36, 'rates' => [14.90, 17.90, 20.90, 20.90, 20.90]],
            2010 => ['term' => 36, 'rates' => [14.90, 17.90, 20.90, 20.90, 20.90]],
            2011 => ['term' => 42, 'rates' => [14.90, 16.90, 19.90, 19.90, 20.90]],
            2012 => ['term' => 42, 'rates' => [12.90, 15.90, 18.90, 19.90, 19.90]],
            2013 => ['term' => 42, 'rates' => [12.90, 15.90, 18.90, 18.90, 18.90]],
            2014 => ['term' => 48, 'rates' => [11.90, 14.90, 17.90, 18.90, 18.90]],
        ]
    );
    define('CREDIT_SCORE_MINIMUM_THRESHOLDS', [720, 610, 580, 530, 489]);
    
    /** @throws Exception */
    function getRateIndexFromCreditScore(int $creditScore): ?int
    {
        foreach (CREDIT_SCORE_MINIMUM_THRESHOLDS as $rateIndex => $minThreshold) {
            if ($creditScore >= $minThreshold) {
                return $rateIndex;
            }
        }
        throw new Exception("Sorry, your credit score ($creditScore) does not qualify for financing");
    }
    
    foreach (range(2000, 2015) as $year) {
        try {
            if (!isset(TERM_RATES_BY_YEAR[$year])) {
                throw new Exception("Sorry, your vehicle year ($year) does not qualify for financing");
            }
            $score = rand(300, 850);
            $rateIndex = getRateIndexFromCreditScore($score);
            $outcome = sprintf(
                'Vehicle Year: %d, Credit Score: %d, Term: %d, Rate: %.2f',
                $year,
                $score,
                TERM_RATES_BY_YEAR[$year]['term'],
                TERM_RATES_BY_YEAR[$year]['rates'][$rateIndex]
            );
        } catch (Exception $e) {
            $outcome = $e->getMessage();
        }
        echo "$outcome\n";
    }
    

    潜在输出:

    Sorry, your vehicle year (2000) does not qualify for financing
    Vehicle Year: 2001, Credit Score: 758, Term: 24, Rate: 15.90
    Sorry, your credit score (401) does not qualify for financing
    Vehicle Year: 2003, Credit Score: 751, Term: 24, Rate: 15.90
    Vehicle Year: 2004, Credit Score: 545, Term: 24, Rate: 22.90
    Sorry, your credit score (481) does not qualify for financing
    Vehicle Year: 2006, Credit Score: 658, Term: 24, Rate: 18.90
    Vehicle Year: 2007, Credit Score: 745, Term: 36, Rate: 15.90
    Vehicle Year: 2008, Credit Score: 836, Term: 36, Rate: 14.90
    Vehicle Year: 2009, Credit Score: 803, Term: 36, Rate: 14.90
    Sorry, your credit score (466) does not qualify for financing
    Vehicle Year: 2011, Credit Score: 792, Term: 42, Rate: 14.90
    Vehicle Year: 2012, Credit Score: 763, Term: 42, Rate: 12.90
    Vehicle Year: 2013, Credit Score: 534, Term: 42, Rate: 18.90
    Vehicle Year: 2014, Credit Score: 493, Term: 48, Rate: 18.90
    Sorry, your vehicle year (2015) does not qualify for financing