I have a Wordpress post meta that has multiple arrays like this.
$costdata = Array(
Array( 'cost_id' => 1, 'cost_category' => 'Travel', 'cost_amount' => '3540')
Array( 'cost_id' => 2, 'cost_category' => 'Materials', 'cost_amount' => '1644')
Array( 'cost_id' => 3, 'cost_category' => 'Travel', 'cost_amount' => '1800')
);
add_post_meta($project_id, 'costdata', $costdata);
What I want to do is to get all 'cost_amount' where 'cost_category' is "Travel"
This is what I've done so far. I get a blank value. No error.
$listtravelcost = get_post_meta($project_id, 'costdata');
/*Calculate Travel cost */
$found_Travel = array_search('Travel', array_column($listtravelcost, 'cost_category'));
$travelbudget = array_column($found_Travel, 'cost_amount');
$printtravelbudget = array_sum($travelbudget);
echo $printtravelbudget;
Instead of array_search, you should use array_filter. array_search will only return the first element it finds that is equal to your needle. array_filter will return all entries in an array, for which the function returns true.
$found_Travel = array_filter($listtravelcost, function($entry) {
return $entry['cost_category'] === 'Travel';
});
The rest of your code should work.
You can use loop:
$travelbudget = [];
foreach ($costdata as $arr) {
if ($arr['cost_category'] === "Travel") {
$travelbudget[] = $arr;
}
}
Related
My question is how can I search an array built this way? Basically there may be a need to repeat the key and this is what I got so far to maybe solve this. If the price is the same for 2 different items I cannot have 2 keys with the same value.
Please feel free to improve on array layout.
$price_list = array(
1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")
);
Provided there will never be any duplication of the second column, you can do this:
$search = "EA_WTRESRVD"; //value to search for
$price_list = array(
1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")
);
$array = array_column($price_list, 0, 1);
echo $array[$search];
I would suggest that if you have a unique product code (SKU), you should use this to index your array.
$products = [
'EA_WTRESRVD' => [
'name' => '...',
'price' => 9.99,
// ...
],
'EA_WTRESRV' => [
'name' => '...',
'price' => 9.99,
// ...
],
];
Then you can access the price of any product by it's SKU.
$price = $products['EA_WTRESRV']['price'];
Here's one way:
<?php
$price_list = [ 1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")];
$search = "EA_WTRESRV";
foreach ($price_list as $arr) {
if (in_array( $search, $arr )) {
echo $search;
}
}
The foreach iterates over the multidimensional array whose elements are each arrays. Each array is inspected by in_array() for the search term.
However, this is not the only way. If you wish to avoid in_array(), you could also code as follows:
<?php
$price_list = [ 1 => array("9.99", "EA_WTRESRVD"),
2 => array("9.99", "EA_WTRESRV")];
$search = "EA_WTRESRV";
$len = strlen($search);
foreach ($price_list as $arr) {
$val = array_values($arr);
foreach($val as $v) {
if ( ( strpos( $v,$search )) !== false) {
if ( strlen($v) == $len) {
echo "$search is in the price list.\n";
}
}
}
}
I need to find the last found element of a specific value from an array. I giving an example in php of what I'm actually seeking for.
$Data = array(
'0' => 'car',
'1' => 'bike',
'2' => 'bus',
'3' => 'bike',
'4' => 'boat'
);
$key = array_search('bike', $Data) // it returns $key = 1 as result which the first element matched inside the array.
I want $key = 3 which is the last matched element.
Any suggestion appreciated.
PHP code demo
<?php
ini_set("display_errors", 1);
$Data = array(
'0' => 'car',
'1' => 'bike',
'2' => 'bus',
'3' => 'bike',
'4' => 'boat'
);
$toSearch="bike";
$index=null;
while($key=array_search($toSearch, $Data))
{
$index=$key;
unset($Data[$key]);
}
echo $index;
Here is the more simple and highly performace way. For it only calculate once, you can access it many time. The live demo.
$data = array_flip($Data);
echo $data['bike'];
after the flip, only keep the last element of the same elements. Here is the print_r($data)
Array
(
[car] => 0
[bike] => 3
[bus] => 2
[boat] => 4
)
We can use array_reverse to reverse array.
$key = array_search('bike', array_reverse($Data,true));
It will return 3.
you can use krsort to sort the array by key.
krsort($Data);
$key = array_search('bike', $Data);
echo $key;
Working example: https://3v4l.org/fYOgN
For this I am created one function it is very easy to use. You can pass only array and parameters.
function text_to_id($value, $arr_master) {
$id_selected = 0;
$search_array = $arr_master;
if (in_array($value, $search_array)) {
$id_selected = array_search($value, $search_array);
// pr($id_selected);exit;
}
if (!$id_selected) {
foreach ($search_array as $f_key => $f_value) {
if (is_array($f_value)) {
if (in_array($value, $f_value)) {
$id_selected = $f_key;
break;
}
} else if ($value == $f_value) {
$id_selected = $f_key;
break;
}
else;
}
}
return $id_selected;
}
this function use like this
$variable = text_to_id('bike', $your_array);
I'm trying to match two arrays, if matched then loop through array value to display them on the page.
This is how I am doing it.
$productIDs = array(
'0' => array(
'product_id' => '565355',
'product_name' => 'stackPDF',
'product_file' => 'http://www.example.com/stack.pdf',
),
'1' => array(
'product_id' => '563423',
'product_name' => 'lostPDF',
'product_file' => 'http://www.example.com/lost.pdf',
),
'3' => array(
'product_id' => '4442',
'product_name' => 'No product',
'product_file' => '',
)
);
function getProducts($productIDs){
$getIDs = explode(',', $_GET['product_id']);
$intersection = array();
foreach($productIDs as $items)
{
$intersection[] = array_intersect($items, $getIDs);
}
if(!empty($intersection)){
return $intersection;
} else {
echo "There are no products available!";
}
}
$getProducts = getProducts($productIDs);
function getDownloads($getProducts){
foreach($getProducts as $item){
print_r($item);
}
}
$getDownloads = getDownloads($getProducts);
In the getProducts() function, I'm checking to see if the product_id in the header match any of the product_id in $productIDs, to only show the available links for those that are in the header.
$getProducts variable has the available product_id that's already matched in an array, and in the $getDownloads I was trying to "If id's are available, loop through and display the product_file parameter value from the multidimensional array" but I can't seem to loop through it, rather I can't figure out how to match it/return the values.
array_filter($array, function($v) use($id){ return $v['product_id'] == $id;})
The easiest way I can think of is:
$item_exists = array_filter($productIDs, function($item) use ($check) {
return md5(json_encode($item)) == md5(json_encode($check));
});
json_encode will serialize the array to string and md5 will create a compare key, if they are equal, it will be inserted in the $item_exists array.
Edit: I was thinking of comparing product objects, but I guess you need the ID's only, you can use something like this:
$existing_values = array_filter($productIDs, function($p)use($getIDs){
return in_array($p["product_id"], $getIDs);
});
I have a string stored in WordPress MySQL database Meta field as serialized string of array of arrays like this:
a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}
When I unserialize that string above it looks like this below...
array (
0 =>
array (
'ab-variation-letter' => 'B',
'ab-variation-title' => 'bbbbbb',
'ab-variation-wysiwyg-editor-' => 'bbbbbbbbbbbb',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
1 =>
array (
'ab-variation-letter' => 'C',
'ab-variation-title' => 'ccccc',
'ab-variation-wysiwyg-editor-' => 'ccccccccccccccccc',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
2 =>
array (
'ab-variation-letter' => 'D',
'ab-variation-title' => 'dddddddd',
'ab-variation-wysiwyg-editor-' => 'd',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
3 =>
array (
'ab-variation-letter' => 'E',
'ab-variation-title' => 'eeeeeeee',
'ab-variation-wysiwyg-editor-' => 'eeeeeee eeeeeeeeeeeee eeeeeeee',
'ab-variation-conversion-count' => '',
'ab-variation-views' => '',
'ab-variation-start-date' => '',
'ab-variation-end-date' => '',
'ab-variation-winner' => '',
),
)
based on this array of arrays above. I want to be able to search for the array that has ab-variation-letter' => 'C' and then be able to update any of the other array key values on that matching array. When done I will need to re-serialize back into a string so I can save it back to the Database table again.
I want to build this PHP function below to be able to take my serialized string of array of arrays and search those arrays for an array that has a key/value matching the passed in $array_key string and then update another keyvalue in that same array and then reserialize the whole thing again.
function updateAbTestMetaData($post_id, $meta_key, $meta_value, $array_key, $new_value){
//get serialized meta from DB
$serialized_meta_data_string = 'a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}';
//un-serialize meta data string
$meta_data_arrays = unserialize($serialized_meta_data_string);
// search array of arrays $meta_data_arrays for array that has a key == $array_key // 'ab-variation-letter' === 'D'
// update the value of any other key on that matching array
// re-serialize all the data with the updated data
}
The end result should allow me to find the array with key 'ab-variation-letter' === 'C' and update the key/value in that matching array with key 'ab-variation-title' and update its current value from 'ccccc' to 'new value' and then re-serialize the whole entire array of arrays back into the original string with only the updated array data updated/
Perhaps throwing together a recursive function that can make use of calling itself could come in handy:
function replaceArrayKeyValue(array &$arr, $whereKey, $whereValue, $replacement) {
$matched = false;
$keys = array_keys($arr);
for ($i = 0; $i < count($keys); $i++)
{
$key = $keys[$i];
if (is_string($arr[$key])) {
if ($key === $whereKey && $arr[$key] === $whereValue) {
if (is_array($replacement)) {
$arr = array_replace_recursive($arr, $replacement);
} else {
$arr[$key] = $replacement;
}
$matched = $key;
break;
}
} else if (is_array($arr[$key])) {
$m = replaceArrayKeyValue($arr[$key], $whereKey, $whereValue, $replacement);
if ($m !== false) {
$matched = $key.'.'.$m;
break;
}
}
unset($key);
}
unset($keys);
return $matched;
}
With the above function, you pass through the source array ($arr), the key you're looking for ($whereKey), the value that it should match ($whereValue) and the replacement value ($replacement).
If $replacement is an array, I've got a array_replace_recursive in place to perform a recursive replacement, allowing you to pass in the changes you'd like to make to the array. For example, in your case:
$data = unserialize(...);
$matchedKey = replaceArrayKeyValue($data, 'ab-variation-letter', 'C', [
'ab-variation-title' => 'My New Title'
]);
$serialized = serialize($data);
You could replace this with array_recursive if you're not wanting the changes to occur further down any nested child arrays.
When using this function, the $data array is modified directly. The result of the function is a joint string of the key path to that value, in this case:
echo $matchedKey; // Result: 1.ab-variation-letter
If you echo print_r($data, true), you get the intended result:
Array (
[0] => Array( ... )
[1] => Array
(
[ab-variation-letter] => C
[ab-variation-title] => My New Title
[ab-variation-wysiwyg-editor-] => ccccccccccccccccc
[ab-variation-conversion-count] =>
[ab-variation-views] =>
[ab-variation-start-date] =>
[ab-variation-end-date] =>
[ab-variation-winner] =>
)
[2] => Array( ... )
[3] => Array( ... )
)
I got it working after some playing around with this code below. Open to other versions as well thanks
$serialized_meta_data_string = 'a:4:{i:0;a:8:{s:19:"ab-variation-letter";s:1:"B";s:18:"ab-variation-title";s:6:"bbbbbb";s:28:"ab-variation-wysiwyg-editor-";s:12:"bbbbbbbbbbbb";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:1;a:8:{s:19:"ab-variation-letter";s:1:"C";s:18:"ab-variation-title";s:5:"ccccc";s:28:"ab-variation-wysiwyg-editor-";s:17:"ccccccccccccccccc";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:2;a:8:{s:19:"ab-variation-letter";s:1:"D";s:18:"ab-variation-title";s:8:"dddddddd";s:28:"ab-variation-wysiwyg-editor-";s:1:"d";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}i:3;a:8:{s:19:"ab-variation-letter";s:1:"E";s:18:"ab-variation-title";s:8:"eeeeeeee";s:28:"ab-variation-wysiwyg-editor-";s:30:"eeeeeee eeeeeeeeeeeee eeeeeeee";s:29:"ab-variation-conversion-count";s:0:"";s:18:"ab-variation-views";s:0:"";s:23:"ab-variation-start-date";s:0:"";s:21:"ab-variation-end-date";s:0:"";s:19:"ab-variation-winner";s:0:"";}}';
$update_on_key = 'ab-variation-title';
$ab_version = 'C';
$new_value = 'new variation title on variation C';
$new_data = updateMetaArrayData($serialized_meta_data_string, $update_on_key, $ab_version, $new_value);
echo '<pre>';
echo $new_data;
function updateMetaArrayData($serialized_meta_data_string, $update_on_key, $ab_version, $new_value){
$new_meta_data_arrays = array();
//un-serialize meta data string
$meta_data_arrays = unserialize($serialized_meta_data_string);
foreach($meta_data_arrays as $key => $value){
$new_meta_data_arrays[$key] = $value;
if(isset($value['ab-variation-letter']) && $value['ab-variation-letter'] == $ab_version){
$new_meta_data_arrays[$key][$update_on_key] = $new_value;
}
}
echo '<pre>';
print_r($new_meta_data_arrays);
$new_serialized_meta = serialize($new_meta_data_arrays);
return $new_serialized_meta;
}
I'm trying to remove an object from an array of objects by its' index. Here's what I've got so far, but i'm stumped.
$index = 2;
$objectarray = array(
0=>array('label'=>'foo', 'value'=>'n23'),
1=>array('label'=>'bar', 'value'=>'2n13'),
2=>array('label'=>'foobar', 'value'=>'n2314'),
3=>array('label'=>'barfoo', 'value'=>'03n23')
);
//I've tried the following but it removes the entire array.
foreach ($objectarray as $key => $object) {
if ($key == $index) {
array_splice($object, $key, 1);
//unset($object[$key]); also removes entire array.
}
}
Any help would be appreciated.
Updated Solution
array_splice($objectarray, $index, 1); //array_splice accepts 3 parameters
//(array, start, length) removes the given array and then normalizes the index
//OR
unset($objectarray[$index]); //removes the array at given index
$reindex = array_values($objectarray); //normalize index
$objectarray = $reindex; //update variable
array_splice($objectarray, $index, 1);
//array_splice accepts 3 parameters (array, start, length) and removes the given
//array and then normalizes the index
//OR
unset($objectarray[$index]); //removes the array at given index
$reindex = array_values($objectarray); //normalize index
$objectarray = $reindex; //update variable
You have to use the function unset on your array.
So its like that:
<?php
$index = 2;
$objectarray = array(
0 => array('label' => 'foo', 'value' => 'n23'),
1 => array('label' => 'bar', 'value' => '2n13'),
2 => array('label' => 'foobar', 'value' => 'n2314'),
3 => array('label' => 'barfoo', 'value' => '03n23')
);
var_dump($objectarray);
foreach ($objectarray as $key => $object) {
if ($key == $index) {
unset($objectarray[$index]);
}
}
var_dump($objectarray);
?>
Remember, your array will have odd indexes after that and you must (if you want) reindex it.
$foo2 = array_values($objectarray);
in that case you won't need that foreach just unset directly
unset($objectarray[$index]);