php while array1 is empty iterate - php

How can iterate with a while loop until array1 is empty.
So far based on several conditions I'm pushing elements from array1 to array2. But I want to iterate array1 until everything from array1 is in array2.
something like:
// or while everything from array1 is on array2
while(array1 is empty){
if(somecondition1)
array_push(array2,"Test");
unset(array1[$i]);
elseif(somecondition2)
array_push(array2,"Test");
unset(array1[$i]);
}
Any ideas will be appreciate it!

count() would work:
while(count(array1)){
if(somecondition1)
array_push(array2,"Test");
elseif(somecondition2)
array_push(array2,"Test");
}
or use do..until
do {
if(somecondition1)
array_push(array2,"Test");
elseif(somecondition2)
array_push(array2,"Test");
} until (count(array1) == 0)

Here's a test I did expanding upon your pseudo-code
$array1 = range( 1, 10 );
$array2 = array();
$i = 0;
while ( !empty( $array1 ) )
{
if ( $array1[$i] % 2 )
{
array_push( $array2, "Test Even" );
unset( $array1[$i] );
} else {
array_push( $array2, "Test Odd" );
unset( $array1[$i] );
}
$i++;
}
echo '<pre>';
print_r( $array1 );
print_r( $array2 );

Related

count how many duplicate keys are in array of objects?

[
{
"playerId":3207,
"playerName":"RyanGarbutt",
"playerPos":"C",
"playerApiId":"5079"
},
{
"playerId":3238,
"playerName":"Max Domi",
"playerPos":"C",
"playerApiId":"5412"
},
{
"playerId":3240,
"playerName":"AnthonyDuclair",
"playerPos":"LW",
"playerApiId":"5441"
}
]
1-> I want to count playerPos(C,LW) occurrences?
2-> How to get data in format like[{"c":"2"},{"LW":"1"}]
You can use array_reduce
$arr = '[{"playerId":3207,"playerName":"RyanGarbutt","playerPos":"C","playerApiId":"5079"},{"playerId":3238,"playerName":"Max Domi","playerPos":"C","playerApiId":"5412"},{"playerId":3240,"playerName":"AnthonyDuclair","playerPos":"LW","playerApiId":"5441"}]';
$arr = json_decode( $arr, true );
$result = array_reduce( $arr , function( $c, $v ) {
isset( $c[ $v[ "playerPos" ] ] ) ? $c[ $v[ "playerPos" ] ]++ : $c[ $v[ "playerPos" ] ] = 1;
return $c;
}, array() );
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[C] => 2
[LW] => 1
)
Doc: http://php.net/manual/en/function.array-reduce.php
Without loop, conditions and callback function.
$arr = '[{"playerId":3207,"playerName":"RyanGarbutt","playerPos":"C","playerApiId":"5079"},{"playerId":3238,"playerName":"Max Domi","playerPos":"C","playerApiId":"5412"},{"playerId":3240,"playerName":"AnthonyDuclair","playerPos":"LW","playerApiId":"5441"}]';
$arr = json_decode( $arr, true );
$result = array_count_values(array_column($arr,"playerPos"));
print_r($result);
Output
Array (
[C] => 2
[LW] => 1
)
Working example
Demo
You can try something like this :
1/ First, create two var you will use as counter of occurences of "C" and "LW" :
$C = 0;
$LW = 0;
2/ Loop through your array with a foreach loop and test each time if the value of your obj for the key "playerPos" is equal to "C" or "LW", then add +1 for your counter var :
foreach($array as $obj) {
$test = $obj['playerPos'];
if ($test == "C")
$C++;
else if ($test == "LW")
$LW++;
}
3/ Then you need to check the value of each var to know the number of occurences.
Is this what you are looking for?
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$data =
'[{
"playerId":3207,"playerName":"RyanGarbutt","playerPos":"C","playerApiId":"5079"},{
"playerId":3238,"playerName":"Max Domi","playerPos":"C","playerApiId":"5412"},{
"playerId":3240,"playerName":"AnthonyDuclair","playerPos":"LW","playerApiId":"5441"}]';
$data=json_decode($data,true);
$uniqueArray = unique_multidim_array($data,'playerPos');
print_r($uniqueArray);
print_r(count($uniqueArray));

PHP make a multidimensional associative array from key names in a string separated by brackets

I have a string with a variable number of key names in brackets, example:
$str = '[key][subkey][otherkey]';
I need to make a multidimensional array that has the same keys represented in the string ($value is just a string value of no importance here):
$arr = [ 'key' => [ 'subkey' => [ 'otherkey' => $value ] ] ];
Or if you prefer this other notation:
$arr['key']['subkey']['otherkey'] = $value;
So ideally I would like to append array keys as I would do with strings, but that is not possible as far as I know. I don't think array_push() can help here. At first I thought I could use a regex to grab the values in square brackets from my string:
preg_match_all( '/\[([^\]]*)\]/', $str, $has_keys, PREG_PATTERN_ORDER );
But I would just have a non associative array without any hierarchy, that is no use to me.
So I came up with something along these lines:
$str = '[key][subkey][otherkey]';
$value = 'my_value';
$arr = [];
preg_match_all( '/\[([^\]]*)\]/', $str, $has_keys, PREG_PATTERN_ORDER );
if ( isset( $has_keys[1] ) ) {
$keys = $has_keys[1];
$k = count( $keys );
if ( $k > 1 ) {
for ( $i=0; $i<$k-1; $i++ ) {
$arr[$keys[$i]] = walk_keys( $keys, $i+1, $value );
}
} else {
$arr[$keys[0]] = $value;
}
$arr = array_slice( $arr, 0, 1 );
}
var_dump($arr);
function walk_keys( $keys, $i, $value ) {
$a = '';
if ( isset( $keys[$i+1] ) ) {
$a[$keys[$i]] = walk_keys( $keys, $i+1, $value );
} else {
$a[$keys[$i]] = $value;
}
return $a;
}
Now, this "works" (also if the string has a different number of 'keys') but to me it looks ugly and overcomplicated. Is there a better way to do this?
I always worry when I see preg_* and such a simple pattern to work with. I would probably go with something like this if you're confident in the format of $str
<?php
// initialize variables
$str = '[key][subkey][otherkey]';
$val = 'my value';
$arr = [];
// Get the keys we want to assign
$keys = explode('][', trim($str, '[]'));
// Get a reference to where we start
$curr = &$arr;
// Loops over keys
foreach($keys as $key) {
// get the reference for this key
$curr = &$curr[$key];
}
// Assign the value to our last reference
$curr = $val;
// visualize the output, so we know its right
var_dump($arr);
I've come up with a simple loop using array_combine():
$in = '[key][subkey][otherkey][subotherkey][foo]';
$value = 'works';
$output = [];
if(preg_match_all('~\[(.*?)\]~s', $in, $m)) { // Check if we got a match
$n_matches = count($m[1]); // Count them
$tmp = $value;
for($i = $n_matches - 1; $i >= 0; $i--) { // Loop through them in reverse order
$tmp = array_combine([$m[1][$i]], [$tmp]); // put $m[1][$i] as key and $tmp as value
}
$output = $tmp;
} else {
echo 'no matches';
}
print_r($output);
The output:
Array
(
[key] => Array
(
[subkey] => Array
(
[otherkey] => Array
(
[subotherkey] => Array
(
[foo] => works
)
)
)
)
)
Online demo

using 2 loops in PHP foreach(...)

I have this PHP foreach loop:
foreach($emails_list as $email)
but i want to do something like
foreach($emails_list as $email and $forename_list as $forename)
my code above the foreach loop is:
$sql2="SELECT * from contacts where company_sequence = '".$customersequence."' and contactstatus = '' ";
$rs2=mysql_query($sql2,$conn) or die(mysql_error());
while($result2=mysql_fetch_array($rs2))
{
$emails_list[] = $result2["email"];
}
si i want to be able to include $result["forename"]; within the loop too
will the above work to make 2 loops?
Not sure if understand, but try use for instead:
$emails_list = array("01#gmail.com", "02#gmail.com", "03#gmail.com", "04#gmail.com");
$forename_list = ("01 something", "02 something", "03 something", "04 something");
if($emails_list == $forename_list){
$count = count($emails_list);
for($i=0;$i<$count;$i++){
echo 'Email: '.$emails_list[$i].', Name: '.$forename_list[$i];
}
} else { echo 'Troubles'; }
there is no way to do this in foreach in a one statment
for this use for loop like
for ($i=0;$i<=count($emails_list); $i++) {
echo $emails_list[$i];
echo $forename_list[$i];
}
All the examples listed with a basic for loop will work fine for numeric arrays, however what about associative arrays?
The best way to do this would be something like the following:
$arr_1 = array( 'foo'=>'bar', 'fizz'=>'bang' );
$arr_2 = array( 'hello'=>1, 2=>'world' );
$array_size = count( $arr_1 ); // NOTE: This assumes the arrays are of the same size.
// Reset the internal array pointers
reset( $arr_1 );
reset( $arr_2 );
for ($i = 0; $i < $array_size; $i++ ) {
$first_array_element = current( $arr_1 );
$second_array_element = current( $arr_2 );
// code here
next( $arr_1 );
next( $arr_2 );
}
This will handle both associative and numeric arrays.

PHP Problem with array_count_values

I need to get one time occurence on my array, with my code I get only first result here is my example code:
$arr=array("a","a","b","c","d");
$arrs=array_count_values($arr);
for ($i=0; $i<count($arr); $i++)
{
if($arrs[$arr[$i]]==1)
{
//do something...in this example i expect to receive b c and d
}
}
Thanks in advance
ciao h
$arr=array("a","a","b","c","d");
$arrs=array_count_values($arr);
for ($i=0; $i<count($arr); $i++)
{
if($arrs[$arr[$i]]==1)
{
echo $arr[$i];
}
}
That should display bcd
$arr=array("a","a","b","c","d");
$result = array();
$doubles = array();
while( !empty( $arr ) ) {
$value = array_pop( $arr );
if( !in_array( $value, $arr )
&& !in_array( $value, $doubles ) ) {
$result[] = $value;
}
else {
$doubles[] = $value;
}
}
May be you've miss your real results:
$arr=array("a","a","b","c","d");
$arrs=array_count_values($arr);
/*
now $arrs is:
array (
'a' => 2,
'b' => 1,
'c' => 1,
'd' => 1,
)
*/
foreach($arrs as $id => $count){
if($count==1) {
// do your code
}
}
/*******************************************************/
/* usefull version */
/*******************************************************/
$arr=array("a","a","b","c","d");
$arrs=array_count_values($arr);
foreach($arr as $id ){
if($arrs[$id]==1){
// do your code
echo "$id is single\n";
}
}
You just need to retrieve any value which only occurs once in the array, right? Try this:
$arr=array("a","a","b","c","d");
$arrs=array_count_values($arr);
foreach ($arrs as $uniqueValue => $count)
{
if($value == 1) {
echo $uniqueValue;
}
}
array_count_values returns an associative array where the key is the value found and its value is the number of times it occurs in the original array. This loop simply iterates over each unique value found in your array (i.e. the keys from array_count_values) and checks if it was only found once (i.e. that key has a value of 1). If it does, it echos out the value. Of course, you probably want to do something a bit more complex with the value, but this works as a placeholder.
$count = 0;
foreach(array("a","a","b","c","d") as $v){
if($v == 1){$count++;}
}

Remove dupes/sort from a Array of Associative Arrays in PHP

I have a array of associative arrays
aa[] = ('Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 );
aa[] = ('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 );
aa[] = ('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>44 );
aa[] = ('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 );
aa[] = ('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>433 );
aa[] = ('Tires'=>23, 'Oil'=>33, 'Spark Plugs'=>44 );
Two Questions
How can I remove duplicates according tot he field 'Oil'
is there a array_unique which I can provide a callback which acts as a custom comparator?
How can I sort by a custom field 'Spark Plugs'
I don't know of a function you can use to do this. You will have to do a foreach over the values of the array and do the uniqueness checking manually.
Use the usort() function and provide a custom comparator.
Instead of manually going and doing the usual duplicate checking, I did this
$aa2 = array()
foeach($aa as $key => $value) {
$aa2[$value['Oil']] = $value;
}
$aa = $aa2;
Then sorting was done by the key...
For question 1, I think array_filter is what you need.
And, like Brian says, usort for your second question.
The issue with remove dupes this way, is how do you determine which values remain, since you're talking about partial uniqueness.
This solution below just keeps the first to appear in index-order. It's not exactly elegant, but it works.
<?php
$aa = array();
$aa[] = array('Tires'=>100, 'Oil'=>10, 'Spark Plugs'=>4 );
$aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 );
$aa[] = array('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>44 );
$aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 );
$aa[] = array('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>433 );
$aa[] = array('Tires'=>23, 'Oil'=>33, 'Spark Plugs'=>44 );
echo '<pre>';
print_r( arrayUniqeBySubKey( $aa, 'Oil' ) );
echo '</pre>';
function arrayUniqeBySubKey( $array, $key )
{
$indexAggregates = array();
foreach ( $array as $idx => $subArray )
{
$indexAggregates[$subArray[$key]][] = $idx;
}
foreach ( $indexAggregates as $originalIndexes )
{
$numOriginals = count( $originalIndexes );
if ( 1 == $numOriginals )
{
continue;
}
for ( $i = 1; $i < $numOriginals; $i++ )
{
unset( $array[$originalIndexes[$i]] );
}
}
return $array;
}
You can indeed use array_filter for filtering your data:
$bb = array_filter($aa, function($item) {
static $tmp = array();
if ($filter = !in_array($item['Oil'], $tmp)) {
$tmp[] = $item['Oil'];
}
return $filter;
});
This uses a static variable inside the function to "remember" the Oil already returned. This works, because $tmp is used only during the execution of array_filter. If you wrap this into a function and call it multiple times for example, $tmp will always be an empty array for the first call of the function provided to array_filter.
The second task, the sorting, can be done using usort with a custom sorting function:
usort($bb, function($a, $b) {
return ($a['Spark Plugs'] > $b['Spark Plugs']
? 1
: -1);
});

Categories