我有一个多维数组:
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(从from
到to
而在相反方向有-1,2表示“两个方向。” / p>
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);
}
}
答案 0 :(得分:1)
我不会为你写这个,但这是一个好的开始:
$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 :(得分:0)
我认为这是某种游戏,所以让我们打电话给玩家1&#34;名字出现在&#34;来自&#34;场和&#34;球员2&#34;名字出现在&#34; to&#34;字段。
根据我的理解,你认为玩家1的价值为正,而玩家2的价值为负。然后你将&#34;中的两个值从玩家1加到玩家2和#34;记录并丢弃从玩家2到玩家1&#34;记录。
根据该规则,Corrupt_Support
最终应为0,而不是2
基本上,在合并你的记录之后,你将无法区分完全没有任何行动和相互取消的行动。
此外,没有规则选择&#34;胜利者&#34;,即&#34;来自&#34;球员将被保留,导致可能不切实际的结果
如果你有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哈希表加速合并并选择&#34;赢家&#34;按照字母顺序:
// 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