I have an array with the following structure :
$array = array(
array("animal" => "dog","color" => "black"),
array("animal" => "cat","color" => "white"),
array("animal" => "mouse","color" => "grey")
);
Now I need to execute a function on every value of animal, say make the values uppercase. This is the expected output :
array(3) {
[0]=>
array(2) {
["animal"]=>
string(3) "DOG"
["color"]=>
string(5) "black"
}
[1]=>
array(2) {
["animal"]=>
string(3) "CAT"
["color"]=>
string(5) "white"
}
[2]=>
array(2) {
["animal"]=>
string(5) "MOUSE"
["color"]=>
string(4) "grey"
}
}
When I do
for (int i=0; i<=$array.size(); i++) {
$array["animal"] = array_map('strtoupper', $array["animal"]);
}
I get this error:
<b>Parse error</b>: syntax error, unexpected 'i' (T_STRING), expecting ';' in <b>[...][...]</b> on line <b>15</b><br />
You can achieve this using following ways:
<?php
$array = array(
array("animal"=>"dog","color"=>"black"),
array("animal"=>"cat","color"=>"white"),
array("animal"=>"mouse","color"=>"grey")
);
foreach ($array as $key => $value) {
foreach ($value as $key1 => $value1) {
if($key1 == 'animal'){
$keys = ucfirst($value1);
$array[$key][$key1]=$keys;
}
}
}
echo "<pre>";print_r($array);
?>
You can also use array_walk Function of PHP
array_walk
$array = array(
array("animal"=>"dog","color"=>"black"),
array("animal"=>"cat","color"=>"white"),
array("animal"=>"mouse","color"=>"grey")
);
$array_map = array_walk($array, 'walk_array');
function walk_array(&$item, $key){
$item['animal'] = strtoupper($item['animal']);
}
echo '<pre>';
print_r($array);
Solution
You could use a for() loop to iterate through you animals. You'll have to count the number of animals you got first with the count() function cast to a variable. Then, you'll be able to make uppercase on your animal index with the strtoupper() function. Also note that you can use the new PHP syntax for arrays like so [] which is a quicker way to do it.
Source-code
<?php
$animals = [
[
'animal' => 'dog',
'color' => 'black'
],
[
'animal' => 'cat',
'color' => 'white'
],
[
'animal' => 'mouse',
'color' => 'grey'
]
];
for ($i = 0; $i < count($animals); $i++)
{
$animals[$i]['animal'] = strtoupper($animals[$i]['animal']);
}
echo '<pre>';
print_r($animals);
echo '</pre>';
Result
Array
(
[0] => Array
(
[animal] => DOG
[color] => black
)
[1] => Array
(
[animal] => CAT
[color] => white
)
[2] => Array
(
[animal] => MOUSE
[color] => grey
)
)
Demo.
PHP : for loop.
PHP : count().
PHP : strtoupper().
PHP : arrays.
Related
I got output from one of the WordPress table cells. The following value is displayed.
$allcoinkey=get_option('_transient_mcw-custom-data');
var_dump($allcoinkey);
and the output:
[0]=>
array(2) {
["slug"]=>
string(7) "bitcoin"
["keywords"]=>
string(30) "بیتکوین,بیت کوین"
}
[1]=>
array(2) {
["slug"]=>
string(8) "ethereum"
["keywords"]=>
string(27) "اتریوم,اتاریوم"
}
}
How do I access keyword values where slug=bitcoin without foreach?
i use this sample code:
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
?>
You can do it like this:
<?php
$allcoinkey = [
[
'slug' => 'bitcoin',
'keywords' => 'بیتکوین,بیت کوین',
],
[
'slug' => 'ethereum',
'keywords' => 'اتریوم,اتاریوم',
],
];
$bitcoinKeywords = current(array_filter($allcoinkey, static function (array $cryptoCurrency) {
return $cryptoCurrency['slug'] === 'bitcoin';
}))['keywords'];
echo $bitcoinKeywords;
I need to extract data from elements with keys that start with foo. from the below array:
[
'name' => 'Bar',
'location' => 'Baz',
'foo.2021-02-01' => '50000.00',
'foo.2021-03-01' => '50000.00',
'foo.2021-04-01' => '50000.00',
'foo.2021-05-01' => '',
]
After identifying qualifying keys, I need to create a new indexed array of associative rows using the date substring from the original keys like so:
[
['date' => '2021-02-01', 'value' => '50000.00'],
['date' => '2021-03-01', 'value' => '50000.00'],
['date' => '2021-04-01', 'value' => '50000.00'],
['date' => '2021-05-01', 'value' => ''],
]
I've been able to extract the keys like so:
$keys = array_keys($theData[0]);
foreach ( $keys as $key ) {
if ( preg_match( '/foo.*/', $key ) ) {
$line = explode('.', $key);
$item[]['name'] = $line[1];
}
}
but I'm losing the values.
I then tried looping through the array manually and rebuilding the desired outcome, but the keys will change so I don't know how future-proof that would be.
Is there a wildcard approach I can take to achieve this?
You almost had it:
<?php
$theData = [
'name' => 'Bar',
'location' => 'Baz',
'foo.2021-02-01' => '50000.00',
'foo.2021-03-01' => '50000.00',
'foo.2021-04-01' => '50000.00',
'foo.2021-05-01' => ''
];
$item = [];
// No need for array_keys(), foreach() can already do this
foreach( $theData as $key => $value )
{
// check if the key starts with foo.
// Regular expressions are heavy; if you'd like then substitute with:
// if ( substr( $key, 0, 4 ) === 'foo.' )
if ( preg_match( '/^foo\\./', $key ) )
{
// foo. is 4 chars long so substring from the fourth index till the end
$item[] = [
'date' => substr( $key, 4 ),
'value' => $value
];
}
}
var_dump( $item );
Output:
array(4) {
[0]=>
array(2) {
["date"]=>
string(10) "2021-02-01"
["value"]=>
string(8) "50000.00"
}
[1]=>
array(2) {
["date"]=>
string(10) "2021-03-01"
["value"]=>
string(8) "50000.00"
}
[2]=>
array(2) {
["date"]=>
string(10) "2021-04-01"
["value"]=>
string(8) "50000.00"
}
[3]=>
array(2) {
["date"]=>
string(10) "2021-05-01"
["value"]=>
string(0) ""
}
}
A simple loop, checking for the key starting with foo. and then a little code to replace foo. in the key with nothing will do the trick
If you have PHP8 or >
$arr = [
'name' => 'Bar',
'location' => 'Baz',
'foo.2021-02-01' => '50000.00',
'foo.2021-03-01' => '50000.00',
'foo.2021-04-01' => '50000.00',
'foo.2021-05-01' => ''
];
$new = [];
foreach ($arr as $k => $v){
if ( str_starts_with( $k , 'foo.' ) ) {
$new[] = ['date' => str_replace('foo.', '', $k), 'value' => $v];
}
}
print_r($new);
RESULT
Array
(
[0] => Array
([date] => 2021-02-01, [value] => 50000.00)
[1] => Array
([date] => 2021-03-01, [value] => 50000.00)
[2] => Array
([date] => 2021-04-01, [value] => 50000.00)
[3] => Array
([date] => 2021-05-01, [value] => )
)
Alternatively, for PHP versions prior to PHP8
$new = [];
foreach ($arr as $k => $v){
if ( strpos( $k , 'foo.') !== FALSE && strpos( $k , 'foo.') == 0 ) {
$new[] = ['date' => str_replace('foo.', '', $k), 'value' => $v];
}
}
Using str_starts_with and explode
$arr = [];
foreach ($theData as $k => $v){
if (str_starts_with($k, "foo."))
$arr[] = ["date" => explode(".", $k)[1], "value" => $v];
}
var_dump($arr);
sscanf() is an ideal function to call which will both check for qualifying strings and extract the desired trailing date value. It doesn't use regex, but it does require a placeholder %s to target the date substring. If a given string doesn't qualify, no element is pushed into the result array.
Code: (Demo) (without compact())
$result = [];
foreach ($array as $key => $value) {
if (sscanf($key, 'foo.%s', $date)) {
// $result[] = ['date' => $date, 'value' => $value];
$result[] = compact(['date', 'value']);
}
}
var_export($result);
If you remove the optional technique of using compact(), this solution makes fewer function calls than all other answers on this page.
I would probably only use regex if I wanted to strengthen the validation for qualifying key strings. (Demo)
$result = [];
foreach ($array as $key => $value) {
if (preg_match('~^foo\.\K\d{4}-\d{2}-\d{2}$~', $key, $m)) {
$result[] = ['date' => $m[0], 'value' => $value];
}
}
var_export($result);
I have an array $array
$array =>
(
['name'] => (
"Ronaldo","Ribery","Bale","Messi"
),
['rank'] => (
2,4,1,3
)
)
Now How can i sort the array DESC using rank field along with the name
Expected output ->
$array =>
(
['name'] => (
"Ribery","Messi","Ronaldo","Bale"
),
['rank'] => (
4,3,2,1
)
)
A valid use for oft-misunderstood array_multisort()
<?php
$array = [
'name' => ["Ronaldo","Ribery","Bale","Messi"],
'rank' => [2,4,1,3]
];
array_multisort(
$array['rank'], SORT_DESC, SORT_NUMERIC,
$array['name'], SORT_ASC, SORT_STRING
);
var_dump($array);
array(2) {
'name' =>
array(4) {
[0] =>
string(6) "Ribery"
[1] =>
string(5) "Messi"
[2] =>
string(7) "Ronaldo"
[3] =>
string(4) "Bale"
}
'rank' =>
array(4) {
[0] =>
int(4)
[1] =>
int(3)
[2] =>
int(2)
[3] =>
int(1)
}
}
Check out this php article also if you want your two arrays to have a relation than you could better write it like this:
array(
array(
name => 'Messi',
rank => 4,
),
etc..
);
Why not change your data structure to be able to work with objects?
class Player {
public $name; // would be better as private and add getters
public $rank;
public function __construct($name, $rank) {
$this->name = $name;
$this->rank = $rank;
}
}
Then fill your array (I'm not familiar with soccer):
$players = [ // or array(...) if you are using older PHP
new Player('Foo', 3),
new Player('Bar', 1),
new Player('FooBar', 2)
];
Then you can use the regular sort:
// or a function name, if using older PHP
usort($players, function (Player $a, Player $b) {
if ($a->rank == $b->rank) {
return 0;
}
return ($a->rank < $b->rank) ? -1 : 1;
});
I have an array like this
$rows = array(
array(
'fruit.name' => 'Apple',
'fruit.colour' => 'Red',
'fruit.weight' => '0.1',
'vegetable.name' => 'Carrot',
'vegetable.colour' => 'Orange',
'vegetable.weight' => '0.05'
),
array(
'fruit.name' => 'Banana',
'fruit.colour' => 'Yellow',
'fruit.weight' => '0.7',
'vegetable.name' => 'Potato',
'vegetable.colour' => 'Brown',
'vegetable.weight' => '0.6'
)
);
And i want to be able to sort the array into 2 other arrays called 'fruits' and 'vegetables' based on the first part of the key name so up to the decimal point. With this array I should have 2 rows in each of the fruits and vegetable arrays.
I have this code but it doesn't work and I can't see what I'm doing wrong.
$fruits = array();
$vegetables = array();
foreach($rows as $row)
{
foreach($row as $key => $value)
{
if('fruit' == substr($key, 0, strpos($key, '.')))
{
$fruits[$key] = $row;
}
else
{
$vegetables[$key] = $row;
}
}
}
echo "<pre>"; var_dump($fruits); echo "</pre>";
When i do a var_dump i get this
array(3) {
["fruit.name"]=>
array(6) {
["fruit.name"]=>
string(6) "Banana"
["fruit.colour"]=>
string(6) "Yellow"
["fruit.weight"]=>
string(3) "0.7"
["vegetable.name"]=>
string(6) "Potato"
["vegetable.colour"]=>
string(5) "Brown"
["vegetable.weight"]=>
string(3) "0.6"
}
["fruit.colour"]=>
array(6) {
["fruit.name"]=>
string(6) "Banana"
["fruit.colour"]=>
string(6) "Yellow"
["fruit.weight"]=>
string(3) "0.7"
["vegetable.name"]=>
string(6) "Potato"
["vegetable.colour"]=>
string(5) "Brown"
["vegetable.weight"]=>
string(3) "0.6"
}
["fruit.weight"]=>
array(6) {
["fruit.name"]=>
string(6) "Banana"
["fruit.colour"]=>
string(6) "Yellow"
["fruit.weight"]=>
string(3) "0.7"
["vegetable.name"]=>
string(6) "Potato"
["vegetable.colour"]=>
string(5) "Brown"
["vegetable.weight"]=>
string(3) "0.6"
}
}
Any help please getting this to separate the array into 2 arrays each containing either fruits or vegetables.
This seems to work:
$rows = array(
array(
'fruit.name' => 'Apple',
'fruit.colour' => 'Red',
'fruit.weight' => '0.1',
'vegetable.name' => 'Carrot',
'vegetable.colour' => 'Orange',
'vegetable.weight' => '0.05'
),
array(
'fruit.name' => 'Banana',
'fruit.colour' => 'Yellow',
'fruit.weight' => '0.7',
'vegetable.name' => 'Potato',
'vegetable.colour' => 'Brown',
'vegetable.weight' => '0.6'
)
);
$fruits = $vegs = array();
foreach ($rows as $arrays) {
$fruit = array();
$veg = array();
foreach ($arrays as $key => $val) {
$index = substr($key, strpos($key, ".") + 1);
if('fruit' == substr($key, 0, strpos($key, '.'))){
$fruit[$index] = $val;
} else {
$veg[$index] = $val;
}
}
$fruits[] = $fruit;
$vegs[] = $veg;
}
var_dump($fruits, $vegs);
(Please overlook the fact I've called one of the vars $vegs)
Hope this helps!
I didn't run the code, but it looks like you want:
$fruits[$key] = $value;
-AND-
$vegetables[$key] = $value;
I am trying to figure out how I can move an array element to another spot. Is this possible?
Here is my example the var_dump array:
array
'person' =>
array
'first_name' =>
array
'...'
'last_name' =>
array
'...'
'rank' =>
array
'...'
'score' =>
array
'...'
'item' =>
array
'...'
'work' =>
array
'company' =>
array
'...'
'phone' =>
array
'...'
And of course there are values in the '...', but just to simplify it. So I need to move "score" before "rank", so the output will show score first before rank, is that possible?
Now I know the array push/pop/shift/unshift but none of those would help me here I think.
Please note, I have no control of this array...I am receiving it as is...
basically it is coming from a Wordpress plugin and it has a filter for these fields so I am using this to catch it.
add_filters( 'work_rank_fields', 'custom_order');
function custom_order($fields) {
var_dump($fields); //what you see on top
}
Using a sample array like you gave us, you could try something like this.
$sample = array(
'person' => array(
'first_name' => array('first'),
'last_name' => array('last'),
'rank' => array('rank'),
'score' => array('score'),
'item' => array('item')
),
'work' => array(
'company' => array('company'),
'phone' => array('phone')
)
);
function reorder_person( $sample )
{
extract( $sample['person'] );
// the desired order below for the keys
$sample['person'] = compact('first_name','last_name','score','rank','item');
return $sample;
}
$sample = reorder_person( $sample );
Now your var_dump of $sample should display score before rank
array(2) {
'person' =>
array(5) {
'first_name' =>
array(1) {
[0] =>
string(5) "first"
}
'last_name' =>
array(1) {
[0] =>
string(4) "last"
}
'score' =>
array(1) {
[0] =>
string(5) "score"
}
'rank' =>
array(1) {
[0] =>
string(4) "rank"
}
'item' =>
array(1) {
[0] =>
string(4) "item"
}
}
'work' =>
array(2) {
'company' =>
array(1) {
[0] =>
string(7) "company"
}
'phone' =>
array(1) {
[0] =>
string(5) "phone"
}
}
}
A little clumsy but, your wordpress filter custom_order function then might look like:
function custom_order( $fields ) {
$a = array();
foreach( $fields['person'] as $key => $value )
{
if ( $key == 'rank' ) continue; // wait until we get score first
if ( $key == 'score' )
{
$a['score'] = $value; // add score first, then rank
$a['rank'] = $fields['person']['rank'];
continue;
}
$a[$key] = $value;
}
$fields['person'] = $a;
return $fields;
}
I'm not sure which is the order criteria but I guess one of this functions can help you. Take a look particularly to last three. You just have to create the appropriate comparison function