PHP group repeated elements in array - php

How can the array be separated into groups of identical elements (concatenated chars).
For example, I have this array:
Array(
[0] => 1
[1] => 1
[2] => 1
[3] => 2
[4] => 2
[5] => 1
)
and want to group all identical numbers in only one element, bringing the together with concatenation to get something like this:
Array(
[0] => 111
[1] => 22
[2] => 1
)

To group all identical elements by concatenating them together (will not work for concatenating just the neighboring identical elements)
$arr = array (1,1,1,2,2,1);
$sum = array_count_values($arr);
array_walk($sum, function(&$count, $value) {
$count = str_repeat($value, $count);
});
print_r($sum);
Output
Array (
[1] => 1111
[2] => 22 )
Or for concatenating just the neighboring identical elements
$prev=null;
$key=0;
foreach ( $arr as $value ) {
if ($prev == $value){
$res[$key] .= $value;
} else {
$key++;
$res[$key] = $value;
$prev=$value;
}
}
print_r($res);
Output
Array (
[1] => 111
[2] => 22
[3] => 1 )

Here two functions
1 will return
Array
(
[1] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
)
[2] => Array
(
[0] => 2
[1] => 2
)
)
as output and second one will return
Array
(
[1] => 1111
[2] => 22
)
as output
$array = array(
1,1,1,2,2,1
);
print_r(groupArray($array));
print_r(groupSame($array));
function groupArray($array){
$temp = array();
foreach($array as $value){
if(!isset($temp[$value])){
$temp[$value] = array();
}
array_push($temp[$value],$value);
}
return $temp;
}
function groupSame($array){
$temp = array();
foreach($array as $value){
if(!isset($temp[$value])){
$temp[$value] = "";
}
$temp[$value] .= $value;
}
return $temp;
}

<?php
$i=0;
foreach($Arrays as $key=>$val) {
if (!isset($array[$i]))
$array[$i]=$val;
else if (!isset($mem) || $val==$mem)
$array[$i]=10*$array[$i]+$mem;
else
$i++;
$mem=$val;
}
?>

$array = array(1,1,1,2,2,1);
$start = "";
$new_array = array();
foreach($array as $v){
$v = (string)$v;
if($start==$v){
$count = count($new_array) - 1;
$val = $new_array[$count].$v;
$new_array[$count] = $val;
} else{
$new_array[] = $v;
}
$start = $v;
}
var_dump($new_array);
Tested and its working..
Output > array(3) { [0]=> string(3) "111" [1]=> string(2) "22" [2]=> string(1) "1" }

$newarray = array_unique($oldarray);
$count = array_count_values($oldarray);
foreach($newarray as &$val){
$val = str_repeat($val,$count[$val]);
}
http://codepad.org/FUf0n8sz

Related

Combine same indexes of array

I have an array which as dynamic nested indexes in e.g. I am just using 2 nested indexes.
Array
(
[0] => Array
(
[0] => 41373
[1] => 41371
[2] => 41369
[3] => 41370
)
[1] => Array
(
[0] => 41378
[1] => 41377
[2] => 41376
[3] => 41375
)
)
Now I want to create a single array like below. This will have 1st index of first array then 1st index of 2nd array, 2nd index of first array then 2nd index of 2nd array, and so on. See below
array(
[0] =>41373
[1] => 41378
[2] => 41371
[3] => 41377
[4] => 41369
[5] => 41376
[6] => 41370
[7] => 41375
)
You can do something like this:
$results = [];
$array = [[1,2,3,4], [1,2,3,4], [1,2,3,4]];
$count = 1;
$size = count($array)-1;
foreach ($array[0] as $key => $value)
{
$results[] = $value;
while($count <= $size)
{
$results[] = $array[$count][$key];
$count++;
}
$count = 1;
}
I think you need something like this:
function dd(array $arrays): array
{
$bufferArray = [];
foreach($arrays as $array) {
$bufferArray = array_merge_recursive($bufferArray, $array);
}
return $bufferArray;
}
$array1 = ['41373','41371','41369','41370'];
$array2 = ['41378','41377', '41376', '41375'];
$return = array();
$count = count($array1)+count($array2);
for($i=0;$i<($count);$i++){
if($i%2==1){
array_push($return, array_shift($array1));
}
else {
array_push($return, array_shift($array2));
}
}
print_r($return);
first count the arrays in the given array, then count the elements in the first array, than loop over that. All arrays should have the same length, or the first one should be the longest.
$laArray = [
['41373','41371','41369','41370'],
['41378', '41377', '41376', '41375'],
['43378', '43377', '43376', '43375'],
];
$lnNested = count($laArray);
$lnElements = count($laArray[0]);
$laResult = [];
for($lnOuter = 0;$lnOuter < $lnElements; $lnOuter++) {
for($lnInner = 0; $lnInner < $lnNested; $lnInner++) {
if(isset($laArray[$lnInner][$lnOuter])) {
$laResult[] = $laArray[$lnInner][$lnOuter];
}
}
}
this would be the simplest solution:
$firstarr = ['41373','41371','41369','41370'];
$secondarr = ['41378','41377','41376','41375'];
$allcounged = count($firstarr)+count($secondarr);
$dividedintotwo = $allcounged/2;
$i = 0;
while ($i<$dividedintotwo) {
echo $firstarr[$i]."<br>";
echo $secondarr[$i]."<br>";
$i++;
}

Explode array's data and make new array

I have this array:
Array
(
[0] => Array
(
[0] => 1
[1] => a,b,c
)
[1] => Array
(
[0] => 5
[1] => d,e,f
)
)
I want the final array to be this:
Array
(
[0] => Array
(
[0] => 1
[1] => a
)
[1] => Array
(
[0] => 1
[1] => b
)
[2] => Array
(
[0] => 1
[1] => c
)
[3] => Array
(
[0] => 5
[1] => d
)
[4] => Array
(
[0] => 5
[1] => e
)
[5] => Array
(
[0] => 5
[1] => f
)
)
This is what I did:
<?php
$array = array(array(1,"a,b,c"),array(5,"d,e,f"));
$temp=array();
$count = 0;
foreach($array as $arr){
$rows = explode(",",$arr[1]);
foreach($rows as $row){
$temp[$count] = $arr;
$temp[$count][1] = $row;
$count++;
}
}
print_r($temp);
?>
This totally works but I was wondering if there was a better way to do this. This can be very slow when I have huge data.
Try like this way...
<?php
$array = array(array(1,"a,b,c"),array(5,"d,e,f"));
$temp=array();
$count = 0;
foreach($array as $arr){
$rows = explode(",",$arr[1]);
foreach($rows as $row){
$temp[$count][] = $arr[0];
$temp[$count][] = $row;
$count++;
}
}
/*print "<pre>";
print_r($temp);
print "<pre>";*/
?>
Here's a functional approach:
$result = array_merge(...array_map(function(array $a) {
return array_map(function($x) use ($a) {
return [$a[0], $x];
}, explode(",", $a[1]));
}, $array));
Try it online.
Or simply with two loops:
$result = [];
foreach ($array as $a) {
foreach (explode(",", $a[1]) as $x) {
$result[] = [$a[0], $x];
}
}
Try it online.
Timing these reveals that a simple loop construct is ~8 times faster.
functional: 4.06s user 0.08s system 99% cpu 4.160 total
loop: 0.53s user 0.05s system 102% cpu 0.561 total
If you need other way around,
$array = array(array(1, "a,b,c"), array(5, "d,e,f"));
$temp = [];
array_walk($array, function ($item, $key) use (&$temp) {
$second = explode(',', $item[1]);
foreach ($second as $v) {
$temp[] = [$item[0], $v];
}
});
print_r($temp);
array_walk — Apply a user supplied function to every member of an array
Here is working demo.

Merge two dimensional array in PHP

for a long time can't resolve smth looking like as very simple matter... I want merge a two dimensional arrays.
The example:
$arr1 = {
[532] =
{
[0] = "11"
[1] = "12"
}
[273] =
{
[0] = "99"
}
}
$arr2 = {
[532] =
{
[0] = "11"
[1] = "13"
}
}
And the result of merging should be, a map on common keys, exactly like that array:
$result = {
[532] =
{
[0] =
{
[0] = "11"
[1] = "12"
}
[1] =
{
[0] = "11"
[1] = "13"
}
}
[273]
[0] =
{
[0] = "99"
}
[1] =
{
}
}
I try sometihng like that:
$result = $arr1;
foreach ($arr2 as $key => $value) {
$result[$key] = isset($result[$key]) ? array_merge([$result[$key]], [$value]) : [$value];
}
But it doesnt work if $arr2 is empty :(
For the second array checking, you need to use isset() either array set or not:
Example:
<?php
$arr1 = array('532'=>array('11','12'),'273'=>array('99'));
$arr2 = array('532'=>array('11','13'));
$newArr = array();
foreach ($arr1 as $key => $value) {
if(isset($arr2[$key])){
$newArr[$key][] = $value;
$newArr[$key][] = $arr2[$key];
}
else{
$newArr[$key] = $value;
}
}
echo "<pre>";
print_r($newArr);
?>
Result:
Array
(
[532] => Array
(
[0] => Array
(
[0] => 11
[1] => 12
)
[1] => Array
(
[0] => 11
[1] => 13
)
)
[273] => Array
(
[0] => 99
)
)
Further more, if you want to merge both same index than you can use array_merge() some thing like that:
<?php
$arr1 = array('532'=>array('11','12'),'273'=>array('99'));
$arr2 = array('532'=>array('11','13'));
$newArr = array();
foreach ($arr1 as $key => $value) {
if(isset($arr2[$key])){
$newArr[$key][] = array_merge($value,$arr2[$key]);
}
else{
$newArr[$key] = $value;
}
}
echo "<pre>";
print_r($newArr);
?>
Result:
Array
(
[532] => Array
(
[0] => Array
(
[0] => 11
[1] => 12
[2] => 11
[3] => 13
)
)
[273] => Array
(
[0] => 99
)
)
Note that, ist script, will give you result as you need with unique index.
Second script will give you all values in one single array.
Probably something like this
$arr1 = {
[532] =
{
[0] = "11"
[1] = "12"
}
[273] =
{
[0] = "99"
}
}
$arr2 = {
[532] =
{
[0] = "11"
[1] = "13"
}
}
$newarray = array();
foreach ($arr1 as $key => $value) {
$cu = $arr1[$key];
$newarray[$key][] = $cu;
if(!isset($arr2[$key])) {
$newarray[$key][] = array();
}
else {
$newarray[$key][] = $arr2[$key];
}
}
foreach ($arr2 as $key => $value) {
if(!isset($newarray[$key])) {
$newarray[$key][] = $arr2[$key];
}
}

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.

Group pairs in array

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);

Categories