【问题标题】:Anyway to simplify this rats nest of foreach loops?无论如何要简化这个foreach循环的老鼠巢?
【发布时间】:2011-11-07 02:53:09
【问题描述】:

这可行,但比地狱更丑陋,基本上它是遍历子数组的两个单独部分,查看两个子数组的值中是否存在除 1 之外的最大公分母,如果存在,则将基值乘以1.5

抱歉,提前写了草率的代码。

error_reporting(E_ALL);
ini_set('display_errors', '1');

class CSVParser
{

    public $output = NULL;
    public $digits = NULL;

    public function __construct($file)
    {


        if (!file_exists($file)) {
            throw new Exception("$file does not exist");
        }

        $this->contents = file_get_contents($file);
        $this->output = array();
        $this->digits = array();
        $this->factor = array();
    }

    public function parse($separatorChar1 = ',', $separatorChar2 = ';', $enclosureChar = '"', $newlineChar = "\n")
    {

        $lines = explode($newlineChar, $this->contents);
        foreach ($lines as $line) {
            if (strlen($line) == 0) continue;
            $group = array();
            list($part1, $part2) = explode($separatorChar2, $line);
            $group[] = array_map(array($this, "trim_value"), explode($separatorChar1, $part1), array("$enclosureChar \t"));
            $group[] = array_map(array($this, "trim_value"), explode($separatorChar1, $part2), array("$enclosureChar \t"));
            $this->output[] = $group;
        }
    }

    private function trim_value($value, $chars)
    {
        return preg_replace("#^( |" . $chars . ")+#", '', $value);
    }


    private function gcd($x,$y) 
    {
        do {
            $rest=$x%$y;
        $x=$y;
        $y=$rest;
        } while($rest!==0);
        return $x;
    }

    public function algorithm()
    {
        $alpha = array(
            'c' => str_split('bcdfghjklmnpqrstvwxz'),
            'v' => str_split('aeiouy')
        );
        $i=$k=0;
        foreach ($this->output as $item) {
            $cnt = 0;
            $this->digits[$i] = array();
            foreach ($item as $part) {
                $this->digits[$i][$cnt] = array();
                $new = array();
                foreach ($part as $str) { 
                    $v = count(array_intersect(str_split($str), $alpha['v']));
                    $c = count(array_intersect(str_split($str), $alpha['c']));
                    $t = strlen(str_replace(' ', '', $str));

                    $new = ($cnt == 0) 
                        ? array('v' => $v, 'c' => $c, 't' => $t, 'm' => ($t%2) ? $v * 1.5 : $c) 
                        : array('v' => $v, 'c' => $c, 't' => $t);

                    $this->digits[$i][$cnt][] = $new;
                }
                $cnt++;
            }
            $i++;
        }
        $h=$cuml=0; 
            foreach($this->digits as &$slice) { 
            foreach($slice[0] as &$sliceName){ 

                foreach($slice[1] as $sliceProduct) { 
                foreach($sliceProduct as $pKey=>$pVal) { 

                    foreach($sliceName as $nKey=>$nVal) { 
                        $tmp[$h] = ($this->gcd($pVal,$nVal) != 1) ? ++$cuml:'';
                    } 
                } 
                    $tmp[$h] = $sliceName['m']*$cuml*1.5; 
                    $h++; 
                    $cuml=0; 
                }$h=0; 

            $sliceName['f'] = $tmp; 
            $tmp=''; 
            } 

            } 
        foreach($this->digits as &$u){unset($u[1]);} 
    } 

}

$parser = new CSVParser("file.csv");
$parser->parse();   //print_r($parser->output);
$parser->algorithm();   print_r($parser->digits);

每个请求的 CSV 样本

Jeff Goes, Mika Enrar;Triple Threat, Dogs on  Bikes
Sonny Ray, Lars McGarvitch, Jason McKinley;Kasabian, Lords of Acid, Hard-Fi

输出

Array
(
    [0] => Array
    (
        [0] => Array
            (
                [0] => Array
                    (
                        [v] => 3
                        [c] => 3
                        [t] => 8
                        [m] => 3
                        [f] => Array
                            (
                                [0] => 40.5
                                [1] => 4.5 // Remainder.. So 'Jeff Goes' => 'Dogs on Bikes'
                            )

                    )

                [1] => Array
                    (
                        [v] => 3
                        [c] => 4
                        [t] => 9
                        [m] => 4.5
                        [f] => Array
                            (
                                [0] => 67.5 // High Score! So 'Mika Enrar' => 'Triple Threat'
                                [1] => 13.5
                            )

                    )

            )

    )

    [1] => Array
    (
        [0] => Array
            (
                [0] => Array
                    (
                        [v] => 4
                        [c] => 2
                        [t] => 8
                        [m] => 2
                        [f] => Array
                            (
                                [0] => 24
                                [1] => 12
                                [2] => 24 // Next Highest 'Sonny Ray' => 'Hard-Fi'
                            )

                    )

                [1] => Array
                    (
                        [v] => 3
                        [c] => 8
                        [t] => 14
                        [m] => 8
                        [f] => Array
                            (
                                [0] => 84 // High Score! (This is really a tie, but 'm' has the highest secondary value so...) 
                                [1] => 60 // 'Lars McGarvitch => 'Kasabian'
                                [2] => 84
                            )

                    )

                [2] => Array
                    (
                        [v] => 5
                        [c] => 5
                        [t] => 13
                        [m] => 7.5
                        [f] => Array
                            (
                                [0] => 0
                                [1] => 0 // The only one left 'Jason McKinley' => 'Lords of Acid'
                                [2] => 11.25
                            )

                    )

            )

    )

)

它的作用

到目前为止,此类所做的是将 csv 拆分为一个数组,将内容拆分为 ;然后进入两个子数组。计算两者的辅音和元音,找出每个 C V 或混合字母对的两个小节之间是否存在最大公分母,并创建一个值来为产品分配一个带。

真正需要做什么

生成的最高值应与创造该高值的频段相关联。所以我真正想做的是将一个名字与一个乐队联系起来,这取决于它最终产生的分数有多高。我已经完成了一半 =(

正如你们所看到的,这段代码实际上是一团糟。我真正想要的只是根据我生成的数字为乐队指定一个名称。

【问题讨论】:

  • 我为你修复了你的代码。请在发布前尝试清理它。缩进错误、间距不一致等,真的很难让人看懂。
  • 也许array_walk_recursive 可能是一个选项。 (虽然没有费心阅读/理解您的代码。)
  • 废话,Brian 我粘贴了你修复的内容,你介意编辑它以向我展示你在单独的代码块中做了什么吗?
  • ehime,感谢您发布其余相关代码,但我不知道它完成了什么。您能否还包括一个示例 csv 输入和相应的输出,并描述转换是如何完成的?
  • 当然,请稍等,我将编写一个输入 csv 并将其发布在代码块下。我会在下面评论它是如何工作的(到目前为止)

标签: php oop loops methods foreach


【解决方案1】:

我必须同意这里的其他人......但我想补充一下:

与其寻找如何遍历 $this->digits 更简单地说,你应该强烈考虑重新考虑 $this->digits中的数据结构。

此外,将所有内容集中到一个数组中并不总是有意义的。但是当它这样做时,可以考虑结构,使其直观且易于遍历。

如果没有有关此操作的更多信息,我们无法建议如何重组您的数据/类。首先是给我们一个样本$this->digits 数组的样子。此外,有关您的问题的更多信息会很好(例如如何使用此方法)。

【讨论】:

  • 我推出了整个班级,以便您可以看到它,也许它是如何工作的。我同意我是以一种倒退的方式来做这件事,但不幸的是,因为我不是一个真正的 OO 程序员,所以我真的在为我在这里所做的事情而苦苦挣扎。也许你能帮我弄清楚布赖恩
【解决方案2】:

如果它有效,你为什么要改变它?表现?重构?生意变了?要求变了吗?清洁代码撒玛利亚人?童子军规则?

当我遇到“意大利面条代码”时,除非我绝对必须更改它,否则我不会理会它。也就是说,我会编写几个单元测试来验证“意大利面条代码”的输出,这样我就知道我没有破坏任何东西或让事情变得更糟。

【讨论】:

  • 我正试图从代码中榨取一些性能,如果没有对内容和方式进行大量解释,很难将其传递给初级人员。
猜你喜欢
  • 2012-01-11
  • 2012-05-01
  • 2022-01-08
  • 1970-01-01
  • 2020-06-12
  • 2020-11-21
  • 1970-01-01
  • 2020-07-06
  • 2015-01-04
相关资源
最近更新 更多