Group pairs in array - php

I'm trying to group airlines with relations into single chains.
Array
(
[0] => Array
(
[0] => Aeroflot
[1] => S7
[2] => Transaero
)
[1] => Array
(
[0] => Alitalia
[1] => Lufthansa
)
[2] => Array
(
[0] => Transaero
[1] => United
)
[3] => Array
(
[0] => United
[1] => Alitalia
)
[4] => Array
(
[0] => Volotea
[1] => Iberia
)
[5] => Array
(
[0] => Transaero
[1] => Aeroflot
)
)
From that array I need to find connections between elements and combine it to groups. Expected results:
Array
(
[0] => Array
(
[0] => Aeroflot
[1] => S7
[2] => Transaero
[3] => United
[4] => Alitalia
[5] => Lufthansa
)
[1] => Array
(
[0] => Volotea
[1] => Iberia
)
)
Can anyone help with that? I've tried a dozen of ways but still get no success.
The most closest way I've tried which works but not in all cases:
function array_searchRecursive($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && array_searchRecursive($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
foreach ($newarr as $key => $airlines)
{
foreach ($airlines as $lastkey => $airline)
{
$index = array_searchRecursive($airline,$newarr);
echo $airline.$index."\n";
if ($index !== false)
{
$newarr[$index] = array_merge($newarr[$index],$airlines);
$lastarr[] = $index;
}
}
}
But it doesn't match all values in array.

Recursive function will help you. You are welcome )
$arr = array(
array('Aeroflot','S7','Transaero'),
array('Alitalia','Lufthansa'),
array('Transaero','United'),
array('United','Alitalia'),
array('Volotea','Iberia'),
array('Transaero','Aeroflot')
);
function getConnections($arr,$curr_line_n=0,$num=0) {
for($i=0;$i<count($arr[$curr_line_n]);$i++) {
$cur_air_name = $arr[$curr_line_n][$i];
for($k=$curr_line_n+1; $k<count($arr); $k++) {
for($l=0;$l<count($arr[$k]);$l++) {
if ($arr[$k][$l]==$cur_air_name) {
$arr[$curr_line_n] = array_values(array_unique(array_merge($arr[$curr_line_n],$arr[$k])));
array_splice($arr,$k,1);
$num++;
$arr = getConnections($arr,$curr_line_n,$num);
}
}
}
}
$num++;
$curr_line_n++;
if ($curr_line_n!=count($arr)) {
$arr = getConnections($arr,$curr_line_n,$num);
}
return $arr;
}
print_r(getConnections($arr));

As per your example you are just grouping sub arrays by taking first sub array as reference. for example if you have any elements common in first sub array and in subsequent sub arrays then you combine them into one sub array.
<?php
$arr = array(
array('a', 'b', 'c', 'd'),
array('d', 't'),
array('t', 'f'),
array('k', 'o'),
array('p', 'z')
);
$arr_implode = array();
foreach ($arr as $key => $value) {
if (is_array($value)) {
$arr_implode[$key] = implode('', $value);
} else {
$arr_implode[$key] = $value;
}
}
$arr_key = array();
$result = array();
$count = count($arr_implode);
$tempj = 0;
for ($i = 0; $i <= $count; $i++) {
$flag = FALSE;
for ($j = ($i + 1); $j < $count; $j++) {
similar_text($arr_implode[$i], $arr_implode[$j], $percent);
if ($percent > 0) {
$result[] = array_merge($arr[$i],$arr[$j]);
break;
} else {
$result[] = $arr[$j];
break;
}
}
}
foreach($result as $key => $val){
$result[$key] = array_unique($val);
}
echo "<pre>";
print_r($result);
echo "</pre>";
?>
Try this code.

$arr = [
['Aeroflot', 'S7', 'Transaero'],
['Alitalia', 'Lufthansa'],
['Transaero', 'United'],
['United', 'Alitalia'],
['Volotea', 'Iberia'],
['Transaero', 'Aeroflot']
];
$hash = [];
$result = [];
foreach($arr as $set){
foreach($set as $el){
if(!$hash[$el]) $hash[$el] = [] ;
$hash[$el] = array_merge($hash[$el], $set);
}
}
function merge_connections(&$h, $key){
if(!$h[$key]) return [];
$data = [$key];
$rels = $h[$key];
unset($h[$key]);
foreach($rels as $rel){
if($rel==$key) continue;
$data = array_merge($data, merge_connections($h, $rel));
}
return $data;
}
foreach(array_keys($hash) as $company){
if(!$hash[$company]) continue;
array_push($result, merge_connections($hash, $company));
}
print_r($result);

Related

Determine whether array key value is blank

I have an array like below, as you can see the last array [adad] value is blank, how can I write an if statement to tell whether this is blank.
Array
(
[K] => Array
(
[0] => mabel__chan
[1] => mabel chan
)
[B] => Array
(
[0] => kieron br
)
[C] => Array
(
[0] => a br
[1] => a
)
[adad] => Array
(
[0] =>
)
)
I have tried doing this
if (count(array_filter($array)) == 0) {}
Pseudo code
if(array[key] == blank) {
echo "is blank";
} else {
echo "isn't blank";
}
**PHP Script this is how I get my data from mongoDB*
The answer below is working correctly when I use echos but now when I'm trying to push into new arrays its broken somewhere I get no data back anymore.
$col = "A" . $user->agencyID;
$db = $m->rules;
$collection = $db->$col;
$id = $_POST['ruleID'];
$search = array(
'_id' => new MongoId($id)
);
$cursor = $collection->find($search);
$validTagsArray = array();
$validArray = array();
foreach ($cursor as $key => $value) {
$temp = array_walk($array, function($v, $k) {
if (count(array_filter($v)) === 0) {
foreach ($value['AutoFix'] as $keyTwo => $valTwo) {
$x = 0;
$validTagsArray['data'][] = array($keyTwo, $x);
}
} else {
foreach ($value['AutoFix'] as $keyTwo => $valTwo) {
$x = 0;
foreach ($valTwo as $key => $value) {
$x++;
}
$validTagsArray['data'][] = array($keyTwo, $x);
}
}
});
}
echo json_encode($validTagsArray);
You can try this -
$array = array
(
'K' => array('0' => 'mabel__chan','1' => 'mabel chan'),
'B' => array('0' => 'kieron br'),
'C' => array('0' => 'a br', '1' => 'a'),
'adad' => array('0' => '')
);
$temp = array_walk($array, function($v, $k) {
if(count(array_filter($v)) === 0) { // check the count of non-empty elements in the sub array
echo $k . ' is empty';
}
});
Output
adad is empty
You can write as:
if([adad][0]== " ")
{
}
You can also try this :
foreach($array as $key=>$value){
if(empty($value))
echo "empty";
}

combine arrays and concat value?

Little complex to explain , so here is simple concrete exemple :
array 1 :
Array
(
[4] => bim
[5] => pow
[6] => foo
)
array 2 :
Array
(
[n] => Array
(
[0] => 1
)
[m] => Array
(
[0] => 1
[1] => 2
)
[l] => Array
(
[0] => 1
[1] => 4
[2] => 64
)
And i need to output an array 3 ,
array expected :
Array
(
[bim] => n-1
[pow] => Array
(
[0] => m-1
[1] => m-2
)
[foo] => Array
(
[0] => l-1
[1] => l-4
[2] => l-64
)
Final echoing OUTPUT expected:
bim n-1 , pow m-1 m-2 ,foo l-1 l-4 l-64 ,
I tried this but seems pity:
foreach($array2 as $k1 =>$v1){
foreach($array2[$k1] as $k => $v){
$k[] = $k1.'_'.$v);
}
foreach($array1 as $res =>$val){
$val = $array2;
}
Thanks for helps,
Jess
CHALLENGE ACCEPTED
<?php
$a = array(
4 => 'bim',
5 => 'pow',
6 => 'foo',
);
$b = array(
'n' => array(1),
'm' => array(1, 2),
'l' => array(1, 4, 64),
);
$len = count($a);
$result = array();
$aVals = array_values($a);
$bKeys = array_keys($b);
$bVals = array_values($b);
for ($i = 0; $i < $len; $i++) {
$combined = array();
$key = $aVals[$i];
$prefix = $bKeys[$i];
$items = $bVals[$i];
foreach ($items as $item) {
$combined[] = sprintf('%s-%d', $prefix, $item);
};
if (count($combined) === 1) {
$combined = $combined[0];
}
$result[$key] = $combined;
}
var_dump($result);
?>
Your code may be very easy. For example, assuming arrays:
$one = Array
(
4 => 'bim',
5 => 'pow',
6 => 'foo'
);
$two = Array
(
'n' => Array
(
0 => 1
),
'm' => Array
(
0 => 1,
1 => 2
),
'l' => Array
(
0 => 1,
1 => 4,
2 => 64
)
);
You may get your result with:
$result = [];
while((list($oneKey, $oneValue) = each($one)) &&
(list($twoKey, $twoValue) = each($two)))
{
$result[$oneValue] = array_map(function($item) use ($twoKey)
{
return $twoKey.'-'.$item;
}, $twoValue);
};
-check this demo Note, that code above will not make single-element array as single element. If that is needed, just add:
$result = array_map(function($item)
{
return count($item)>1?$item:array_shift($item);
}, $result);
Version of this solution for PHP4>=4.3, PHP5>=5.0 you can find here
Update: if you need only string, then use this (cross-version):
$result = array();
while((list($oneKey, $oneValue) = each($one)) &&
(list($twoKey, $twoValue) = each($two)))
{
$temp = array();
foreach($twoValue as $item)
{
$temp[] = $twoKey.'-'.$item;
}
$result[] = $oneValue.' '.join(' ', $temp);
};
$result = join(' ', $result);
As a solution to your problem please try executing following code snippet
<?php
$a=array(4=>'bim',5=>'pow',6=>'foo');
$b=array('n'=>array(1),'m'=>array(1,2),'l'=>array(1,4,64));
$keys=array_values($a);
$values=array();
foreach($b as $key=>$value)
{
if(is_array($value) && !empty($value))
{
foreach($value as $k=>$val)
{
if($key=='n')
{
$values[$key]=$key.'-'.$val;
}
else
{
$values[$key][]=$key.'-'.$val;
}
}
}
}
$result=array_combine($keys,$values);
echo '<pre>';
print_r($result);
?>
The logic behind should be clear by reading the code comments.
Here's a demo # PHPFiddle.
//omitted array declarations
$output = array();
//variables to shorten things in the loop
$val1 = array_values($array1);
$keys2 = array_keys($array2);
$vals2 = array_values($array2);
//iterating over each element of the first array
for($i = 0; $i < count($array1); $i++) {
//if the second array has multiple values at the same index
//as the first array things will be handled differently
if(count($vals2[$i]) > 1) {
$tempArr = array();
//iterating over each element of the second array
//at the specified index
foreach($vals2[$i] as $val) {
//we push each element into the temporary array
//(in the form of "keyOfArray2-value"
array_push($tempArr, $keys2[$i] . "-" . $val);
}
//finally assign it to our output array
$output[$val1[$i]] = $tempArr;
} else {
//when there is only one sub-element in array2
//we can assign the output directly, as you don't want an array in this case
$output[$val1[$i]] = $keys2[$i] . "-" . $vals2[$i][0];
}
}
var_dump($output);
Output:
Array (
["bim"]=> "n-1"
["pow"]=> Array (
[0]=> "m-1"
[1]=> "m-2"
)
["foo"]=> Array (
[0]=> "l-1"
[1]=> "l-4"
[2]=> "l-64"
)
)
Concerning your final output you may do something like
$final = "";
//$output can be obtained by any method of the other answers,
//not just with the method i posted above
foreach($output as $key=>$value) {
$final .= $key . " ";
if(count($value) > 1) {
$final .= implode($value, " ") .", ";
} else {
$final .= $value . ", ";
}
}
$final = rtrim($final, ", ");
This will echo bim n-1, pow m-1 m-2, foo l-1 l-4 l-64.

Sort and group array from timestamp

I have the following array:
Array
(
[0] => Array
(
[dest_in_id] => 1
[dest_user_id] => 37251
[dest_inv_user_id] => 37247
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
[1] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
[2] => Array
(
[dest_in_id] => 2
[dest_user_id] => 37251
[dest_inv_user_id] => 37257
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
[3] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
)
Need to review the difference in Timestamp each array and if it <= day (86400), then create an array type:
Array
(
[1387168510] => Array
(
[0] => Array
(
[dest_in_id] => 1
[dest_user_id] => 37251
[dest_inv_user_id] => 37247
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
[1] => Array
(
[dest_in_id] => 2
[dest_user_id] => 37251
[dest_inv_user_id] => 37257
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
)
[1345220045] => Array
(
[0] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
[1] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
)
)
Important note! Keys may be different!
At once appealed to the function usort. Wanted to do something like this:
usort($aInvitesRows, function($a, $b) {
$akey = array_keys($a);
$bkey = array_keys($b);
if (($b[preg_grep("/(.*?)_timestamp/", $bkey)[3]] - $a[preg_grep("/(.*?)_timestamp/", $akey)[3]]) <= 86400) {
return $b[preg_grep("/(.*?)_timestamp/", $bkey)[3]] = array($a, $b);
}
});
Success of this venture was not crowned :(
At this stage, using usort could only sort by Timestamp (*), what do you do - do not know the, address for the help!
*
usort($aInvitesRows, function($a, $b) {
$akey = array_keys($a);
$bkey = array_keys($b);
return strcmp($b[preg_grep("/(.*?)_timestamp/", $bkey)[3]], $a[preg_grep("/(.*?)_timestamp/", $akey)[3]]);
});
function msort($array, $key, $sort_flags = SORT_REGULAR) {
if (is_array($array) && count($array) > 0) {
if (!empty($key)) {
$mapping = array();
foreach ($array as $k => $v) {
$sort_key = '';
if (!is_array($key)) {
$sort_key = $v[$key];
} else {
// #TODO This should be fixed, now it will be sorted as string
foreach ($key as $key_key) {
$sort_key .= $v[$key_key];
}
$sort_flags = SORT_STRING;
}
$mapping[$k] = $sort_key;
}
asort($mapping, $sort_flags);
$sorted = array();
foreach ($mapping as $k => $v) {
$sorted[] = $array[$k];
}
return $sorted;
}
}
return $array;
}
$arr = $aInvitesRows;
$result = array();
$item = array_shift($arr);
$akeys = array_keys($item);
$dt = new \DateTime();
$dt->setTimestamp($item[preg_grep("/(.*?)_timestamp/", $akeys)[3]]);
$dt->setTime(0, 0, 0);
$result[$dt->getTimestamp()] = array($item);
foreach ($arr as $item) {
$akeys = array_keys($item);
$f = false;
foreach ($result as $day => $items) {
$diff = ($item[preg_grep("/(.*?)_timestamp/", $akeys)[3]]) - $day;
if ($diff < 86400 && $diff > 0) {
$result[$day][] = $item;
$f = true;
break 1;
}
}
if (!$f) {
$dt = new \DateTime();
$dt->setTimestamp($item[preg_grep("/(.*?)_timestamp/", $akeys)[3]]);
$dt->setTime(0, 0, 0);
$result[$dt->getTimestamp()] = array($item);
}
}

Covert flat array to Nested Array in PHP

Given the following input:
array('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11')
How can I convert it into this:
array(
'one': array(
'two': 3,
'four': array(5,6,7)
)
'eight': array(
'nine': (
'ten':11
)
}
)
$input = array ('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11');
$result = array ();
foreach ($input as $string) {
$data = array_reverse(explode('/', $string));
$tmp_array = array ();
foreach ($data as $val) {
if (empty($tmp_array)) {
$tmp_array = $val;
} else {
$tmp = $tmp_array;
$tmp_array = array ();
$tmp_array[$val] = $tmp;
}
}
$result = array_merge_recursive($result, $tmp_array);
}
echo "<pre>";
print_r($result);
echo "</pre>";
Output:
Array
(
[one] => Array
(
[two] => 3
[four] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
)
[eight] => Array
(
[nine] => Array
(
[ten] => 11
)
)
)
It would be nice if we saw what you have tried.
$my_array = array('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11');
$result= array();
foreach ($my_array as $val) {
$ref = & $result;
foreach (explode("/", $val) as $val) {
if (!isset($ref[$val])) {
$ref[$val] = array();
}
$ref = & $ref[$val];
}
$ref = $val;
}
var_dump($result);

same values from php array in new array

i have a problem with arrays, there are not my friends :)
i have a this array:
Array
(
[0] => 2012163115
[1] => 2012163115
[2] => 2012161817
[3] => 201214321971
[4] => 201214321971
[5] => 201214321971
)
and i need this with all the variables appear more than once
Array
(
[0] => 2012163115
[1] => 201214321971
)
i try this
foreach ($array as $val) {
if (!in_array($val, $array_temp)) {
$array_temp[] = $val;
} else {
array_push($duplis, $val);
}
}
but the result is
Array
(
[0] => 2012163115
[1] => 201214321971
[2] => 201214321971
)
where is my mistake? thanks for help!
array_unique() is there for you.
EDIT: ops I didn't notice the "more than once" clause, in that case:
$yourArray = array('a', 'a', 'b', 'c');
$occurrences = array();
array_walk($yourArray, function($item) use(&$occurrences){
$occurrences[$item]++;
});
$filtered = array();
foreach($occurrences as $key => $value){
$value > 1 && $filtered[] = $key;
}
var_dump($filtered);
$array = array(
'2012163115',
'2012163115',
'2012161817',
'201214321971',
'201214321971',
'201214321971',
);
$duplication = array_count_values($array);
$duplicates = array();
array_walk($duplication, function($key, $value) use (&$duplicates){
if ($key > 1)
$duplicates[] = $value;
});
var_dump($duplicates);
Please see http://php.net/manual/en/function.array-unique.php#81513
These are added characters to make SO accept the post!
$array_counting = array();
foreach ($array as $val)
if ( ! in_array($val, $array_counting))
{
$array_counting[$val] ++; // counting
}
$array_dups = array();
foreach ($array_counting as $key => $count)
{
if ($count > 1)
$array_dups[] = $key; // this is more than once
}

Categories