Reputation: 561
As the title says I get array looking something like this:
array (size=376)
0 =>
array (size=3)
'source' => int 0
'target' => int 47
'officers' =>
array (size=1)
0 => string 'PARKER, Thomas, Sir' (length=19)
1 =>
array (size=3)
'source' => int 0
'target' => int 104
'officers' =>
array (size=1)
0 => string 'STEVENS, Anne' (length=13)
2 =>
array (size=3)
'source' => int 0
'target' => int 187
'officers' =>
array (size=1)
0 => string 'PARKER, Thomas, Sir' (length=19)
3 =>
array (size=3)
'source' => int 0
'target' => int 229
'officers' =>
array (size=1)
0 => string 'GROTE, Byron' (length=12)
4 =>
array (size=3)
'source' => int 0
'target' => int 244
'officers' =>
array (size=1)
0 => string 'GROTE, Byron' (length=12)
5 =>
array (size=3)
'source' => int 1
'target' => int 60
'officers' =>
array (size=1)
0 => string 'BASON, John' (length=11)
6 =>
array (size=3)
'source' => int 1
'target' => int 92
'officers' =>
array (size=1)
0 => string 'HAUSER, Wolfhart, Dr' (length=20)
If source and target are the same I want to create 1 value in this array for example
Insteed of this:
5 =>
array (size=3)
'source' => int 1
'target' => int 92
'officers' =>
array (size=1)
0 => string 'BASON, John' (length=11)
6 =>
array (size=3)
'source' => int 1
'target' => int 92
'officers' =>
array (size=1)
0 => string 'HAUSER, Wolfhart, Dr' (length=20)
I would want to get
5 =>
array (size=3)
'source' => int 1
'target' => int 92
'officers' =>
array (size=1)
0 => string 'BASON, John' (length=11)
1 => string 'HAUSER, Wolfhart, Dr' (length=20)
My idea to achieve this:
for ($i = 0; $i < count($edges); $i++) {
for ($j = $i + 1; $j < count($edges); $j++) {
if($edges[$i]['source']==$edges[$j]['source']&&$edges[$i]['target']==$edges[$j]['target']){
foreach( $edges[$j]['officers'] as $officer){
array_push($edges[$i]['officers'], $officer);
}
array_splice($edges, $j,1);
}
}
}
It seems to be merging but only 2 values and it isn't deleting old values so:
I got something like :
66 =>
array (size=3)
'source' => int 24
'target' => int 103
'officers' =>
array (size=2)
0 => string 'GILAURI, Irakli' (length=15)
1 => string 'JANIN, Neil' (length=11)
67 =>
array (size=3)
'source' => int 24
'target' => int 103
'officers' =>
array (size=1)
0 => string 'MORRISON, David' (length=15)
So it merget Gilauri and Janin but didn't add Morrison, David to officers array and also Gilauri, Irakli and Janin, Neil have separate row in this array which shouldn't be added.
Upvotes: 0
Views: 51
Reputation: 41820
This is similar to other problems where you can solve this by using a key from the sub-arrays as a key in your merged result. It's just a little different because you need to use more than one key to determine which records should be merged.
I would suggest doing it by just concatenating the two keys.
foreach ($your_array as $item) {
$k = "$item[source].$item[target]";
if (isset($merged[$k])) {
$merged[$k]['officers'] = array_merge($merged[$key]['officers'], $item['officers']);
} else {
$merged[$k] = $item;
}
}
And if you don't like the composite keys, you can do array_values($merged)
afterward to get back to plain numeric keys.
Upvotes: 2
Reputation: 23787
Note that array_splice
rekeys the array each time it is executed. From the documentation:
Note that numeric keys in input are not preserved.
I.e. array_splice($array, 1, 1)
on $array = [0 => 1, 1 => 2, 2 => 3]
will result in [0 => 1, 1 => 3]
.
Thus when you are iterating with a for loop, your index will point one entry further than before for each removed array element.
To remove by index without rekeying, use unset($edges[$j])
instead of the array_splice()
.
Alternatively use a foreach
loop (by reference to operate on the actual loop and not on a copy):
foreach ($edges as $i => &$edge) {
for ($j = $i + 1; $j < count($edges); $j++) {
if ($edge['source'] == $edges[$j]['source'] && $edge['target'] == $edges[$j]['target']) {
foreach ($edges[$j]['officers'] as $officer) {
array_push($edge['officers'], $officer);
}
array_splice($edges, $j, 1);
}
}
}
But I recommend the unset()
alternative as it is much faster (array_splice always recreates the array completely).
Upvotes: 2