我有一个多维数组:
Array
(
[10] => Array
(
[from] => Jack
[to] => Terry
[Bribe] => 0
[Joke_Payment] => 0
[Corrupt_Support] => 1
[Legitimate_Support] => 0
[Obfuscation] => 1
[Legal_Enforcement] => 0
[Whistleblower] => 0
)
[11] => Array
(
[from] => Terry
[to] => Jack
[Bribe] => 0
[Joke_Payment] => 0
[Corrupt_Support] => 1
[Legitimate_Support] => 0
[Obfuscation] => 0
[Legal_Enforcement] => 1
[Whistleblower] => 0
)
)
我想更新上面的数组如下:有一个1(从to
到from
)和一个-1表示相反的方向,一个2表示"两个方向"。
Array ( [10] => Array
(
[from] => Jack
[to] => Terry
[Bribe] => 0
[Joke_Payment] => 0
[Corrupt_Support] => 2
[Legitimate_Support] => 0
[Obfuscation] => 1
[Legal_Enforcement] => -1
[Whistleblower] => 0
) }
如何首先计算它们的交集,然后更新原始数组?
它们的键数量相同,当from
与to
匹配,to
与from
元素匹配时,我想将这两个数组合并为一个。"1"用于表示该属性在from
到to
方向上相关,而-1
表示该属性的方向相反(从to
到from
)。
我当前的代码是:
$fileRelation = explode("'r", $end);
$rowsRelation = array_map('str_getcsv', $fileRelation);
$headerRelation = array_shift($rowsRelation);
$csvArrRelation = array();
$countR = count($headerRelation);
foreach ($rowsRelation as $key => &$row) {
$index = 2;$sum = 0;$sumArr = array();
while ($index < $countR) {
if ($row[$index]>0) {
$sumArr[$sum]=$index; //store row $headerRelation index
$sum++;
}
$index++;
}
if($sum > 0){ //remove element if no relationship exist
foreach ($csvArrRelation as $k => $a) {
if (in_array($row[0], $csvArrRelation[$k]) && in_array($row[1], $csvArrRelation[$k])){
$p = array_values($a);$i = 2;$cp= count($p);
while($i < $cp ){
if($row[$i] == $p[$i]){
$a[$headerRelation[$i]] += $row[$i];
}else{
$a[$headerRelation[$i]] -= $row[$i];
}
$i++;
}
unset( $rowsRelation[$key] );
}
}
$csvArrRelation[] = array_combine($headerRelation, $row);
}
}
我不会为您写这篇文章,但这里有一个好的开始:
$newRelations = [];
$deletions = [];
foreach ($rowsRelation as $key1 => $row1)
{
foreach ($rowsRelation as $key2 => $row2)
{
// Don't compare with self
if ($key1 != $key2)
{
// Have we found a reverse match?
if (
$row1['from'] == $row2['to'] &&
$row1['to'] == $row2['from']
)
{
$newRelations[] = myMerge($row1, $row2);
$deletions[] = $key1;
$deletions[] = $key2;
}
}
}
}
// Delete old rows
foreach ($deletions as $deleteKey)
{
unset($rowsRelation[$deleteKey]);
}
// Add in new rows
$rowsRelation = array_merge($rowsRelation, $newRelations);
function myMerge(array $row1, array $row2)
{
// todo
}
我的策略是将每一行相互比较,如果发现反向匹配,我们就知道应该合并。为了避免损坏foreach
循环,我将新的数组值添加到不同的数组中,并记录我希望从原始数组中删除哪些键。然后在工作完成后将这些内容合并/删除。
我认为这是某种游戏,所以让我们称"玩家1"为名称出现在"from"字段中的玩家,称"玩家2"为名称显示在"to"字段中。
根据我的理解,你认为球员1的价值观是积极的,而球员2的价值观则是消极的。然后将"从玩家1到玩家2"记录中的两个值相加,并丢弃"从玩家2到玩家1"记录。
根据该规则,Corrupt_Support
最终的值应该是0,而不是2。
基本上,在合并记录后,您将无法区分完全没有操作和相互取消的操作。
此外,没有选择"获胜者"的规则,即哪个"来自"的球员将被保留,这可能会导致不切实际的结果
如果你有3名玩家Abe、Bob和Cal,你可以得到任何可能的订单,例如["Abe vs Bob", "Bob vs Cal" and "Cal vs Abe"]
或["Abe vs Bob", "Abe vs Cal" and "Cal vs Bob"]
在后一种情况下,查找Bob的操作将是相当有问题的。
现在,如果你仍然想这样做,这里有一种方法可以利用PHP哈希表来加快合并速度,并根据字母顺序选择"赢家":
// use "from player 1 to player 2" relation as key
foreach ($relations as $r) $relation_pairs[$r['from'].'+'.$r['to']] = $r;
// pick the "winners" according to alphabetic order
ksort ($relation_pairs);
// merge relations
while (list($k,$r) = each($relation_pairs)) // this will take elements deletion into account immediately, contrary to foreach
{
$symetric = $r['to'].'+'.$r['from'];
if (isset($relation_pairs[$symetric])) // found a symetric relation
{
foreach ($relation_pairs[$symetric] as $field=>$value) // combine all numeric fields
if (is_numeric ($value))
$relation_pairs[$k][$field] -= $value;
unset ($relation_pairs[$symetric]); // get rid of symetric relation
}
}
$compressed_relations = array_values ($relation_pairs); // get rid of keys