Jump to content
dumblegate

PHP sort subarrays help

Recommended Posts

Posted

Presupunem ca avem array-ul:


$users = array(
0 => array(
"name" => "Alin",
"ip" => array(
0 => "a.b.c.d",
1 => "d.e.f.g"
)
),
1 => array(
"name" => "Cristina"
"ip" => array(
0 => "1.1.1.1",
1 => "2.2.2.2"
)
),
2 => array(
"name" => "Mihai"
"ip" => array(
0 => "h.i.j.k",
1 => "l.m.n.o"
)
),
3 => array(
"name" => "Cristina"
"ip" => array(
0 => "2.2.2.2",
1 => "3.3.3.3"
)
)

);

Si incerc sa arate asa:


$users = array(
0 => array(
"name" => "Alin",
"ip" => array(
0 => "a.b.c.d",
1 => "d.e.f.g"
)
),
1 => array(
"name" => "Cristina"
"ip" => array(
0 => "1.1.1.1",
1 => "2.2.2.2",
2 => "3.3.3.3"
)
),
2 => array(
"name" => "Mihai"
"ip" => array(
0 => "h.i.j.k",
1 => "l.m.n.o"
)
)

);

Imi da mari batai de cap. Aveti vreo idee?

Posted (edited)


$new_users = array();
for($i=0;$i<count($users);$i++) {
if(!in_array($users[$i]['name'], $new_users[$i])) {
$new_users[] = $users[$i];
}else{
$new_users[$i] = array_merge($users[$i], $new_users[$i]);
$new_users[$i] = array_unique($new_users[$i]);
}
}
print_r($new_users);

Nu am testat, dar chiar daca nu merge, important e sa prinzi ideea.

Edited by GarryOne
Posted (edited)

Da, facand un vector, gol initial, cu proprietatea ca elementele stau mereu sortate in functie de cheia (stringul) data de primul element din oricare element al vectorului initial. Comportamentul va fi similar cu a unui set (o multime, numai ca aia babana e implementata ca un arbore rosu-negru) si pentru fiecare element din vector, deoarece este mereu fix de 2 elemente "name" si "ip", recomand sa-i fie pus continutul intr-un fel de structura ca pair de 2 elemente (nu stiu php / daca se poate sau daca e convenabil).

Ideea algoritmului este sa iterezi vectorul si fiecare element sa-l procesezi pe vectorul initial gol in felul urmator:

- mai intai cauti binar (timp logaritmic - eficient) dupa existenta cheii, adica dupa "name"

- daca exista deja acelasi "name" nu ai decat sa adaugi inca un ip la lista deja existenta cu ipuri

- daca nu exista un "name" (adica s-au intalnit/depasit capetele cautarii binare) atunci inserezi noua "structura" exact in locul unde ti-a esuat cautarea (unde teoretic ar trebui sa fie elementul cautat de tine), ineficienta fiind necesitatea de a muta in jos restul elementelor deja existente, din cauza structurarii liniare a vectorului.

Si in final vei avea o multime cu elemente unice sortate dupa "name" avand ca ipuri toate ipurile colectate corespunzator de la toate elementele din vectorul initial, vezi lower bound. Dar decat sa stai sa implementezi manual (si oricum iese ineficient tocmai din cauza structurii de date alese) folosesti asta unde cheia este "name" iar valoarea o reprezinta un set de ipuri (sau un vector simplu de ipuri apoi mai iterezi o data fiecare element din dictionar si ii sortezi valoarea, adica vectorul de ipuri asta daca tii neaparat sa le sortezi si pe astea).

Edited by cmiN
Posted


$new_users = array();
for($i=0;$i<count($users);$i++) {
$success = 0;
for($a=0;$a<count($new_users);$a++) {
if(!in_array($users[$i]['name'], $new_users[$a])) {
$success++;
}else{
break;
}
}
if(count($new_users) == $success) {
$new_users[] = $users[$i];
}else{
$new_users[$success]['ip'] = array_merge($users[$i]['ip'], $new_users[$success]['ip']);
$new_users[$success]['ip'] = array_unique($new_users[$success]['ip']);
}
}
print_r($new_users);

testat

Posted

bump pentru cei interesati:

 for($i=0;$i<count($users)+1;$i++){ for($j=$i+1;$j<count($users);$j++){ if($ - Pastebin.com

asa am reusit sa o rezolv. putea sa fie mai eficient daca foloseam in_array si array_merge.

cmin, asa a si fost gandirea. m-am adaptat eu pe parcurs.

@garry: rezolvarea ta e mai scurta si mai eficienta. eu m-am complicat. merci!

Posted

Uite o varianta mai scurta.


$new_users = array();
foreach($users as $user) {
if(!isset($new_users[$user['name']]))
$new_users[$user['name']] = array(
'name' => $user['name'],
'ip' => array()
);
$new_users[$user['name']]['ip'] = array_unique(array_merge($user['ip'],$new_users[$user['name']]['ip']));
sort($new_users[$user['name']]['ip']);
}
var_dump($new_users);

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...