无论如何要简化这只老鼠foreach循环的巢? [英] Anyway to simplify this rats nest of foreach loops?
问题描述
这有效,但比地狱更丑陋,基本上是在子数组的两个独立部分中进行迭代,查看两个子数组的值中是否存在除1以外的最大公分母,如果存在,则将基值乘以1.5
This works but is uglier than hell, basically it's iterating through two separate portions of a sub array, seeing if there's a greatest common denominator besides 1 in the values of both sub arrays, and if there is, multiplying the base value by 1.5
很抱歉提前输入草率的代码.
Sorry for the sloppy code ahead of time.
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或混合字母对的两个小节之间是否存在最大的公分母,并创建一个值来为产品指定频段.
What this class does so far is split the csv one array, split content prior to ; and after into two sub arrays. Count the consonants and vowels of both, find if there is a greatest common denominator between the two subsections for each C V or mixed letter pair, and create a value to assign a band to a product.
实际需要做什么
生成的最高值应与创建该高值的波段相关联.因此,我真正要做的就是根据乐队最终产生的分数将名字与乐队联系起来.我大约==
The highest value generated should be associated with the band that created that high value. So what I am trying to really do is associate a name to a band depending on how high of a score it ultimately generates. I'm about half way through =(
正如你们所看到的,从字面上看,这段代码是一团糟.我真正想要的就是根据我生成的数字为乐队分配一个名称.
As you guys can see, this code is a mess, literally. All I really want is to assign a name to a band based on the numbers I'm generating.
推荐答案
我必须在这里与其他所有人达成一致……但我想补充一下:
I have to agree with everyone else here... but I'd like to add:
而不是简单地搜索遍历 $this->digits
,您应该强烈考虑重新考虑 $this->digits
中的数据结构.
此外,将所有内容合并到一个数组中并不总是很有意义.但是,一旦这样做,就可以考虑该结构,以便直观,易于遍历.
Furthermore, lumping everything into a single array doesn't always make sense. But when it does, the structure can be thought out so that it is intuitive and can be traversed easily.
没有有关此操作的更多信息,我们无法建议如何重组您的数据/类.首先是给我们一个示例$this->digits
数组的外观.另外,有关您的问题的更多信息也将是很好的(例如,如何使用此方法).
Without more information about what this is doing, there is no way for us to suggest how to restructure your data / class. A start would be giving us what a sample $this->digits
array looks like. Also, some more information about your problem would be good (like how this method is used).
这篇关于无论如何要简化这只老鼠foreach循环的巢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!