array_flip of a key value for letter and numbers - php

I have an array like this
array(123=>'c', 125=>'b', 139=>'a', 124=>'c', 135=>'c', 159=>'b');
and I want to flip the key/values so that duplicate values become an index for an array.
array(
'a'=>array(139),
'b'=>array(125, 159),
'c'=>array(123, 124, 135)
);
However, array_flip seems to overwrite the keys and array_chunk only splits it based on number values.
Any suggestions?

I think it's going to need you to loop over the array manually. It really shouldn't be hard though...
$flippedArray = array();
foreach( $arrayToFlip as $key => $value ) {
if ( !array_key_exists( $value, $flippedArray ) {
$flippedArray[ $value ] = array();
}
$flippedArray[ $value ][] = $key;
}

function array_flop($array) {
foreach($array as $k => $v) {
$result[$v][] = $k;
}
return array_reverse($result);
}

Related

PHP Transform mixed sequential and associative array to associative array

I would like to build $goal array from $initial only. Any ideas? Thank you
Edit : the question could be how to differentiate associative parts from sequential ones.
$intial=[
"one",
"two"=>"myTwo",
"three",
"four"=>"myFour"
];
$goal=[
"one"=>null,
"two"=>"myTwo",
"three"=>null,
"four"=>"myFour"
];
The 'sequential' parts will have numeric keys, so if your 'associative' keys will always be strings, you could use that to differentiate:
$goal = [];
foreach ($initial as $key => $value) {
if (is_numeric($key)) {
$goal[$value] = null;
} else {
$goal[$key] = $value;
}
}
$goal = [];
foreach($initial as $key => $val){
if(isset($val){
$goal[$key] = $val;
}else{
$goal[$key] = $key;
}
}

Iterate a PHP array from a specific key

I know how to iterate an array in PHP, but I want to iterate an array from a specific key.
Assume that I have a huge array
$my_array = array(
...
...
["adad"] => "value X",
["yy"] => "value Y",
["hkghgk"] => "value Z",
["pp"] => "value ZZ",
...
...
)
I know the key where to start to iterate ("yy"). Now I want to iterate only from this key to another key.
I know that I don't want to do this:
$start_key = "yy";
foreach ($my_array as $key => $v)
{
if ($key == $start_key)
...
}
I was looking for Iterator, but I don't think this is what I need.
Try combining array_search, array_key, and LimitIterator. Using the example from the LimitIterator page and some extra bits:
$fruitsArray = array(
'a' => 'apple',
'b' => 'banana',
'c' => 'cherry',
'd' => 'damson',
'e' => 'elderberry'
);
$startkey = array_search('d', array_keys($fruitsArray));
$fruits = new ArrayIterator($fruitsArray);
foreach (new LimitIterator($fruits, $startkey) as $fruit) {
var_dump($fruit);
}
Starting at position 'd', this outputs:
string(6) "damson" string(10) "elderberry"
There is a limit to this approach in that it won’t loop around the array until the start position again. It will only iterate to the end of an array and then stop. You would have to run another foreach to do the first part of the array, but that can be easily done with the code we already have.
foreach (new LimitIterator($fruits, 0, $startkey-1) as $fruit) {
var_dump($fruit);
}
This starts from the first element, up to the element before the one we searched for.
foreach always resets the array's array pointer. You just can't do that the way you imagine.
You still have a few ways. The foreach way is just skipping everything until you found the key once:
$start_key = "yy";
$started = false;
foreach ($my_array as $key => $v)
{
if ($key == $start_key) {
$started = true;
}
if (!$started) {
continue;
}
// your code
}
You could as well work with the array pointer and use the while (list($key, $v) = each($array)) method:
$start_key = "yy";
reset($array); // reset it to be sure to start at the beginning
while (list($key, $v) = each($array) && $key != $start_key); // set array pointer to $start_key
do {
// your code
} while (list($key, $v) = each($array));
Alternatively, you can just extract the array you want to iterate over like MarkBaker proposed.
Perhaps something like:
foreach(array_slice(
$my_array,
array_search(
$start_key,array_keys($my_array)
),
null,
true) as $key => $v) {}
Demo
You can use array_keys and array_search.
Like this:
$keys = array_keys( $my_array ); // store all of your array indexes in a new array
$position = array_search( "yy" ,$keys ); // search your starting index in the newly created array of indexes
if( $position == false ) exit( "Index doesn't exist" ); // if the starting index doesn't exist the array_search returns false
for( $i = $position; $i < count( $keys ); $i++ ) { // starting from your desired index, this will iterate over the rest of your array
// do your stuff to $my_array[ $keys[ $i ] ] like:
echo $my_array[ $keys[ $i ] ];
}
Try it like this:
$startkey = array_search('yy', array_keys($my_array));
$endkey = array_search('zz', array_keys($my_array));
$my_array2 = array_values($my_array);
for($i = $startkey; $i<=$endkey; $i++)
{
// Access array like this
echo $my_array2[$i];
}
If this pull request makes it through, you will be able to do this quite easily:
if (seek($array, 'yy', SEEK_KEY)) {
while ($data = each($array)) {
// Do stuff
}
}

Create an array with duplicated value from an array (PhP)

I want to create an new array with duplicated MAX value from an array
and put other duplicate value in an other array
$etudiant = array ('a'=>'2','b'=>'5', 'c'=>'6', 'd'=>'6', 'e'=>'2');
and i want this result
$MaxArray = array ('c'=>'6', 'd'=>'6');
$otherarray1 = array ('a'=>'2', 'e'=>'2');
Thank you !
First, find the maximum value:
$etudiant = array ('a'=>'2','b'=>'5', 'c'=>'6', 'd'=>'6', 'e'=>'2');
$maxValue = max($etudiant);
Second, find values that appear more than once:
$dups = array_diff_assoc($etudiant, array_unique($etudiant));
Lastly, check the original arrays for values matching either $maxValue or values that are listed in $dups:
$MaxArray = $OtherArray = $ElseArray = array();
foreach ($etudiant as $key => $value) {
if ($value == $maxValue) {
$MaxArray[$key] = $value;
} else if (in_array($value, $dups)) {
$OtherArray[$key] = $value;
} else {
$ElseArray[$key] = $value;
}
}
You'll get:
$MaxArray: Array
(
[c] => 6
[d] => 6
)
$OtherArray: Array
(
[a] => 2
[e] => 2
)
Note: I wasn't sure if you wanted the $MaxArray to contain the maximum value elements only if it appears more than once in the source array. If so, just change the max call to:
$maxValue = max($dups);
You can use array_values(array_intersect($array1, $array2)) to get duplicated values, and then make a loop to capture the keys which have those values and store them into another array.
$dups = array_values(array_intersect($array1, $array2))
$max = max($dups);
$result = array();
foreach ($array1 as $key => $value){
if (in_array($value, $dups)) {
$result[$key] = $value;
}
}
foreach ($array2 as $key => $value){
if (in_array($value, $dups)) {
$result[$key] = $value;
}
}
$maxArray = array();
foreach ($dups as $key => $value) {
if ($value == $max){
$maxArray[$key] = $value;
}
}
// results are in $dups and $maxArray
If you are looking to find elements with the min and max values from an array, the following will work.
// get min keys
$min_value = min($etudiant);
$min_keys = array_keys($etudiant, $min_value);
// get max keys
$max_value = max($etudiant);
$max_keys = array_keys($etudiant, $max_value);
You could then either rebuild your example arrays with these keys in a loop. Or access them directly, i.e. $etudiant[$min_keys].
Check out the documentation for array_keys, min, max

php array keys problem

I have the following code:
$rt1 = array
(
'some_value1' => 'xyz1',
'some_value2' => 'xyz2',
'value_1#30'=>array('0'=>1),
'value_2#30'=>array('0'=>2),
'value_3#30'=>array('0'=>3),
'value_1#31'=>array('0'=>4),
'value_2#31'=>array('0'=>5),
'value_3#31'=>array('0'=>6),
'some_value3' => 'xyz3',
'some_value4' => 'xyz4',
);
$array_30 = array
(
'0'=>1,
1=>'2',
2=>'3'
);
$array_31 = array
(
'0'=>4,
'1'=>'5',
'2'=>'6'
);
I need to make it an array and insert the array_30 and array_31 into a DB.
foreach($rt1 as $value){
$rt2[] = $value['0'];
}
The question was updated, so here is an updated answer. Quick check, you should really try and update this to whatever more generic purpose you have, but as a proof of concept, a runnable example:
<?php
$rt1 = array
(
'some_value1' => 'xyz1',
'some_value2' => 'xyz2',
'value_1#30'=>array('0'=>1),
'value_2#30'=>array('0'=>2),
'value_3#30'=>array('0'=>3),
'value_1#31'=>array('0'=>4),
'value_2#31'=>array('0'=>5),
'value_3#31'=>array('0'=>6),
'some_value3' => 'xyz3',
'some_value4' => 'xyz4',
);
$finalArrays = array();
foreach($rt1 as $key=>$value){
if(is_array($value)){
$array_name = "array_".substr($key,-2);
${$array_name}[] = $value['0'];
}
}
var_dump($array_30);
var_dump($array_31);
?>
will output the two arrays with the numbers 1,2,3 and 4,5,6 respectivily
i assume you want to join the values of each of the second-level arrays, in which case:
$result = array();
foreach ($rt1 as $arr) {
foreach ($arr as $item) {
$result[] = $item;
}
}
Inspired by Nanne (which reminded me of dynamically naming variables), this solution will work with every identifier after the \#, regardless of its length:
foreach ( $rt1 as $key => $value )
{
if ( false == strpos($key, '#') ) // skip keys without #
{
continue;
}
// the part after the # is our identity
list(,$identity) = explode('#', $key);
${'array_'.$identity}[] = $rt1[$key]['0'];
}
Presuming that this is your actual code, probably you will need to copy the array somewhere using foreach and afterwards create the new array as you wish:
foreach($arr as $key => $value) {
$arr[$key] = 1;
}

How can I get the current array index in a foreach loop?

How do I get the current index in a foreach loop?
foreach ($arr as $key => $val)
{
// How do I get the index?
// How do I get the first element in an associative array?
}
In your sample code, it would just be $key.
If you want to know, for example, if this is the first, second, or ith iteration of the loop, this is your only option:
$i = -1;
foreach($arr as $val) {
$i++;
//$i is now the index. if $i == 0, then this is the first element.
...
}
Of course, this doesn't mean that $val == $arr[$i] because the array could be an associative array.
This is the most exhaustive answer so far and gets rid of the need for a $i variable floating around. It is a combo of Kip and Gnarf's answers.
$array = array( 'cat' => 'meow', 'dog' => 'woof', 'cow' => 'moo', 'computer' => 'beep' );
foreach( array_keys( $array ) as $index=>$key ) {
// display the current index + key + value
echo $index . ':' . $key . $array[$key];
// first index
if ( $index == 0 ) {
echo ' -- This is the first element in the associative array';
}
// last index
if ( $index == count( $array ) - 1 ) {
echo ' -- This is the last element in the associative array';
}
echo '<br>';
}
Hope it helps someone.
foreach($array as $key=>$value) {
// do stuff
}
$key is the index of each $array element
$i = 0;
foreach ($arr as $key => $val) {
if ($i === 0) {
// first index
}
// current index is $i
$i++;
}
The current index is the value of $key. And for the other question, you can also use:
current($arr)
to get the first element of any array, assuming that you aren't using the next(), prev() or other functions to change the internal pointer of the array.
You can get the index value with this
foreach ($arr as $key => $val)
{
$key = (int) $key;
//With the variable $key you can get access to the current array index
//You can use $val[$key] to
}
$key is the index for the current array element, and $val is the value of that array element.
The first element has an index of 0. Therefore, to access it, use $arr[0]
To get the first element of the array, use this
$firstFound = false;
foreach($arr as $key=>$val)
{
if (!$firstFound)
$first = $val;
else
$firstFound = true;
// do whatever you want here
}
// now ($first) has the value of the first element in the array
You could get the first element in the array_keys() function as well. Or array_search() the keys for the "index" of a key. If you are inside a foreach loop, the simple incrementing counter (suggested by kip or cletus) is probably your most efficient method though.
<?php
$array = array('test', '1', '2');
$keys = array_keys($array);
var_dump($keys[0]); // int(0)
$array = array('test'=>'something', 'test2'=>'something else');
$keys = array_keys($array);
var_dump(array_search("test2", $keys)); // int(1)
var_dump(array_search("test3", $keys)); // bool(false)
well since this is the first google hit for this problem:
function mb_tell(&$msg) {
if(count($msg) == 0) {
return 0;
}
//prev($msg);
$kv = each($msg);
if(!prev($msg)) {
end($msg);
print_r($kv);
return ($kv[0]+1);
}
print_r($kv);
return ($kv[0]);
}
based on #fabien-snauwaert's answer but simplified if you do not need the original key
$array = array( 'cat' => 'meow', 'dog' => 'woof', 'cow' => 'moo', 'computer' => 'beep' );
foreach( array_values( $array ) as $index=>$value ) {
// display the current index + value
echo $index . ':' . $value;
// first index
if ( $index == 0 ) {
echo ' -- This is the first element in the associative array';
}
// last index
if ( $index == count( $array ) - 1 ) {
echo ' -- This is the last element in the associative array';
}
echo '<br>';
}

Categories