I'm trying to create a function that shifts array values up a key if the previous key is empty and one after is set. E.g. this array:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string '' (length=0)
'row3' => string '' (length=0)
'row4' => string 'row4' (length=4)
should become this after my function call:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
I do have a working function, however, it uses a lot of if statements and I'm 100% sure that it could be done more efficiently, any ideas on how to achieve efficiently?
Thanks
You can do this in a single line, making use of array_ functions.
$o = array_combine(array_keys($input), array_pad(array_filter($input), count($input), ''));
array_filter will, by default, remove any empty values from the array
array_pad will pad the array to the length of the original array, adding an empty string
array_keys will get the keys of the original array
array_combine will combine the keys with the values
The above would output the following:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
Here's a demo
Lets try this with a big array, and hope this will help you out. The way of question is different but your question is same as
1. Getting empty values at end.
2. Non empty at starting without changing order
3. Without changing keys order
If you think about any array this result come to end.
Try this code snippet here
<?php
$array=$tempArray=array(
'row1' => 'row1',
'row2' => '' ,
'row3' => '',
'row6' => 'row6' ,
'row4' => 'row4' ,
'row5' => '',
'row7' => 'row7' ,
'row8' => ''
);
$result=array();
$tempArray= array_values($tempArray);
$tempArray=array_values(array_filter($tempArray));
foreach(array_keys($array) as $key_key => $key)
{
if(!empty($tempArray[$key_key]))
{
$result[$key]=$tempArray[$key_key];
}
else
{
$result[$key]="";
}
}
print_r($result);
Output:
Array
(
[row1] => row1
[row2] => row6
[row3] => row4
[row6] => row7
[row4] =>
[row5] =>
[row7] =>
[row8] =>
)
unfortunately you did not share your code, so we cannot know what you do exactly
also it would be helpful if you added the array as code we can run directly and do not need to edit/re-create
I would
ignore the keys for processing the list when possible
unset entries that are nor needed any longer
iterate lists with foreach
apart from this you can sort lists in PHP (by value, key; asc, desc; with/without association), they have a nice overview on that in the manual.
example steps:
<?php
$a['row1'] = 'row1';
$a['row2'] = '';
$a['row3'] = '';
$a['row4'] = 'row4';
print_r( $a );
arsort($a);
print_r( $a );
//get rid of double entries
$f=array_flip( $a );
//get rid of empty entries
unset($f['']);
print_r( array_flip( $f ) );
?>
EDIT
$yourarr=array('row1'=>"row1",'row2'=>"",'row3'=>"",'row4'=>"row4");
$array1=array();
$array2=array();
foreach ($yourarr as $key =>$val){
if(empty($val)){
$array2[$key]=$val;
}else{
$array1[$key]=$val;
}
}
$newarr=array_merge($array1,$array2);
//<!-- Try This if you want to remove the empty indexes just put ! infront of the empty and delete the else part and to reset the row count -->
$i=1;
$newarr2=array();
foreach($newarr as $key =>$val){
$newarr2['row'.$i]=$val;
$i++;
}
var_dump($newarr2);
OUTUT
D:\wamp64\www\test\index.php:21:
array (size=4)
'row1' => string 'row1' (length=4)
'row2' => string 'row4' (length=4)
'row3' => string '' (length=0)
'row4' => string '' (length=0)
Related
Currently I have this:
$pattern = array('industry_id','category_id','subcategory_id');
$data = array('advert_id' => string '261501' (length=6)
'advert_type_id' => string '7' (length=1)
'user_id' => string '6221' (length=4)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
'model' => string 'Custom Semi Drop Deck Trailer' (length=29)
'description' => string 'Industry: Trailer );
Then:
array_intersect_key( $data , array_flip($pattern) );
Using array_interect_key & array_flip to get the values from $data based on $pattern, I will get a result like this:
array (size=3)
'category_id' => string '769' (length=3)
'subcategory_id' => string '930' (length=3)
'industry_id' => string '17' (length=2)
Unfortunately as you can see the result key sorting is not the same that I declared in $pattern. Is there a shorthand way to sort it like I declared in $pattern because after this I want to implode the array and do something like this industry_id.category_id.subcategory_id without hard coding the keys.
Since you already figured out array_intersect_key method which will not get you the desired key ordering of $pattern, try this instead:
// since original $pattern is not ASSOC (only vals)
// flip it so defined vals become keys
$pattern_flipped = array_flip($pattern);
$result = array();
foreach ($pattern_flipped as $k => $v) {
if (isset($data[$k])) {
$result[$k] = $data[$k];
}
}
var_dump($result); // test
// can use original 0 1 2 dynamic keys for concatenation
echo $result[$pattern[0]], $result[$pattern[1]], $result[$pattern[2]], '<br>';
// or use hardcoded keys
echo $result['industry_id'], $result['category_id'], $result['subcategory_id'], '<br>';
You know I'm not sure how you're getting the result you describe. I've tried your code and I get
array (size=3)
'industry_id' => string '17' (length=2)
'category_id' => string '769' (length=3)
'subcategory_id' => string '868' (length=3)
You could do this another way though using array_filter
$newData = array_filter($data, function($key) use ($pattern) {
if (in_array($key, $pattern))
return true;
}, ARRAY_FILTER_USE_KEY)
I've got a form which users can add new rows by clicking on a button and automatically, it adds +1 on the field's name.
So for example, I've got my train_id_1, train_type_1 and my user wants to add a new one, so now I've got train_id_2 and train_type_2.
In order to save this in my database, I would like to sort and seperate train_type_1 / train_type_2... to make a foreach and then to save in my database.
So, the var_dump of my $_POST looks like :
array (size=60)
'train_id_1' => string ' 07:36' (length=6)
'train_type_1' => string ' -Z' (length=3)
'user_id_1' => string 'CPN' (length=3)
'event_criter_1' =>
array (size=3)
0 => string 'test' (length=4)
1 => string '234' (length=3)
2 => string '532' (length=3)
'train_id_2' => string ' 08:32' (length=6)
'train_type_2' => string ' -X' (length=3)
'user_id_2' => string 'CPN' (length=3)
'event_criter_2' =>
array (size=3)
0 => string 'TESTG' (length=5)
1 => string 'GGG' (length=3)
2 => string 'AETG' (length=4)
'train_id_3' => string ' 08:36' (length=6)
'train_type_3' => string ' -Z' (length=3)
'user_id_3' => string 'CPN' (length=3)
'event_criter_3' =>
array (size=1)
0 => string '' (length=0)
'train_id_4' => string ' 09:04' (length=6)
'train_type_4' => string ' -X' (length=3)
'user_id_4' => string 'CPN' (length=3)
'event_criter_4' =>
array (size=1)
0 => string '' (length=0)
Do you know how I can make abcd_1 separate from abcd_2 to make my foreach (or another solution) ?
Thank you!
Loop through your array, matching _1 and insert the posted elements as one row. Then increment and match _2 etc..
$postedElements = $_POST;
$elementsPerRow = 4;
$numRows = count($postedElements)/$elementsPerRow;
// loop through the number of 'rows' to insert
for($i=1;$i<=$numRows;$i++){
// Build an array to store matched elements to insert
$elementsToInsert = array();
//process the complete _POST array each time...
foreach($postedElements as $name => $value){
// ...get the 'row' (the bit after the underscore)...
//list($value,$row) = explode('_',$name); // doesn't work for 2 underscores..
$row = end(explode($name)); // This will
if($row == $i){
// ...and add elements that match to an insert array
// $elementsToInsert[] = $name;
$elementsToInsert[$name] = $value;
}
}
// insert $elementsToInsert into DB
}
I think, at first You need to have a amount of records in array through count($arr). Then use usual for loop:
//output of field names
for ($i = 0; $i < count($arr); $i++){
//Work with array
}
Make a new array.
Then add a data from loop into new array.
I think it could help You.
And by which reason You need to sort them?
I have an array in the following format:
0 =>
array (size=4)
'timestamp' => string '1/2/2014 7:59' (length=13)
'phase1' => string '16264' (length=5)
'phase2' => string '16671' (length=5)
'phase3' => string '7146' (length=4)
1 =>
array (size=4)
'timestamp' => string '2/2/2014 7:59' (length=13)
'phase1' => string '16310' (length=5)
'phase2' => string '16105' (length=5)
'phase3' => string '7211' (length=4)
I want to create another array within another item to the array that will add the values of phase1, phase2 and phase3
Something like this.
$total_value[$i]['total'] = $csv_file[$i]['phase1'] + $csv_file[$i]['phase2'] + $csv_file[$i]['phase3'];
I tried using a for loop but it doesn't work:
for($i = 0; i < $size_of_array; $i++ ) {
$total_value[$i]['total'] = $csv_file[$i]['phase1'] + $csv_file[$i]['phase2'] + $csv_file[$i]['phase3'];
}
Try:
foreach($csv_file as $key => $values) {
$total_value[$key]['total'] = $values['phase1'] + $values['phase2'];
//$total_value[$key] = $values['phase1'] + $values['phase2'];
}
I would use the commented line so I just had a single-dimension (easier to work with):
Please see how you can deal with objects using foreach
try using foreach by referring
http://www.php.net/manual/en/language.oop5.iterations.php
I'm using the PHP preg_replace function on a string called $where:
$where = preg_replace( '/data\./', '', $where );
However I'd like to achieve the same expression replacement if $where is an array of an unknown size.
Do I have to set up a loop? Or is there a PHP function to help me out?
Any help would be appreciated.
Many thanks
Okay, here is my input array:
array
0 => null
1 => null
2 =>
array
'condition' =>
array
'column' => string 'start' (length=5)
'operator' => string '>=' (length=2)
'argvalue' => string '2013-11-21 00:00:00' (length=19)
3 =>
array
'condition' =>
array
'column' => string 'start' (length=5)
'operator' => string '<=' (length=2)
'argvalue' => string '2013-11-21 23:59:59' (length=19)
4 => null
Here is my manipulation:
$where = preg_replace('/start\./', 'Alan', $where );
And here is my output:
array
0 => string '' (length=0)
1 => string '' (length=0)
2 => string 'Array' (length=5)
3 => string 'Array' (length=5)
4 => string '' (length=0)
This is returning an Array to String conversion error.
Thanks
PHP docs on the subject argument of preg_replace
subject
The string or an array with strings to search and replace.
If subject is an array, then the search and replace is performed on every entry of subject, and the return value is an array as well.
Try this code :
$text = array( "editpostiddata" ,"editpodatastcat", "ch114","ch112");
$result = preg_replace(array_fill(0, 4, "/data/i"),'', $text);
print_r($result);
I am using PHP 5.3.5, and I am stuck with an error. I have an array
$input = array(
0=>array(
'a'=>'one0',
'b'=>'two0',
'c'=>'three0',
'd'=>'four0',
'e'=>'five0'
),
1=>array(
'a'=>'one1',
'b'=>'two1',
'c'=>'three1',
'd'=>'four1',
'e'=>'five1'
)
);
I use array_splice to remove the initial two values from each array
by using &(value by reference) in foreach
foreach ($input as $bk => &$bv) {
$op[]=array_splice($bv,0,2);
}
Now when I see the $input then it adds a & just before the second array.
var_dump($input); shows this
array
0 =>
array
'c' => string 'three0' (length=6)
'd' => string 'four0' (length=5)
'e' => string 'five0' (length=5)
1 => & <====================================From where this `&` comes?
array
'c' => string 'three1' (length=6)
'd' => string 'four1' (length=5)
'e' => string 'five1' (length=5)
Where does & come from and how does it produce such array? Is it valid?
If I remove & in the foreach, it does not gives me desired array. Am I doing something wrong?
It's pretty counter-intuitive but it isn't actually a bug. When you use references in a loop, you're advised to unset the reference right after the loop:
foreach ($input as $bk => &$bv) {
$op[]=array_splice($bv,0,2);
}
unset($bv);