I'm having a problem lately that's driving me crazy. I have a multi-dimensional array like this:
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
)
'2' => array(
'id' => '3',
'name' => 'test',
'cat' => array(
'a' => '50',
'b' => '40',
'c' => '90'
),
'canvas' => '1'
)
)
);
And i want to search on it using a function like this: search('canvas = 1');
That would return all the arrays, child of db, that have a key canvas with the value of 1. Or, for example:
search('a = 15');
Would return all arrays that have a key, child of cat, named a and with a value of 15.
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
)
);
//checks if array $array contains element with $searchKey key, and $searchVal value
function arrayContains($array, $searchVal, $searchKey) {
if (!is_array($array))
return false;
foreach ($array as $key => $value) {
if ($key === $searchKey && $searchVal === $value)
return true;
if (is_array($value) && arrayContains($value, $searchVal, $searchKey))
return true;
}
return false;
}
function search($a, $search) {
list($searchKey, $searchVal) = explode('=', $search);
$result = array();
foreach($a as $val) {
if (arrayContains($val, $searchVal, $searchKey))
$result[] = $val;
}
return $result;
}
print_r(search($a['db'], "a=15"));
print_r(search($a['db'], "canvas=1"));
Which produces this output(outputs sub-arrays of $a['db'] which contain searched key=>value pair):
Array
(
[0] => Array
(
[id] => 1
[name] => test
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
[1] => Array
(
[id] => 2
[name] => test2
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
)
Array
(
[0] => Array
(
[id] => 3
[name] => test
[cat] => Array
(
[a] => 50
[b] => 40
[c] => 90
)
[canvas] => 1
)
)
Just check the below link if this can help you -
http://php.net/manual/en/function.array-search.php
It contains detailed documentation of php function array_search() and various user codes for searching in multi-dimensional array along with user reviews.
function search($array, $canvas)
{
$result = array();
foreach ($array as $k1 => $v1) {
foreach ($v1 as $k2 => $v2) {
if ($v2['canvas'] == $canvas) {
$result[] = $array[$k1][$k2];
}
}
}
return $result;
}
// $a = your array
print_r(search($a, 1));
Related
Hello i am trying to create data set like
Expected output:-
Array
(
[0] => Array
(
[sku] => sku
[variant_option_one_name] => Color
[variant_option_one_value] => Cyan
),
[1] => Array
(
[sku] => sku
[variant_option_one_name] => Color
[variant_option_one_value] => Red
)
)
but i am not sure what is missing in code.
Here is the code
$array = array(
0 => array(
'id_product_attribute' => '17615',
'id_product' => '2295',
'reference' => '',
'available_date' => '0000-00-00',
'vend_id' => null,
'id_shop' => '1',
'id_attribute_group' => '1',
'is_color_group' => '1',
'group_name' => 'Color',
'attribute_name' => 'Cyan',
'id_attribute' => '1',
),
1 => array(
'id_product_attribute' => '17616',
'id_product' => '2295',
'reference' => '',
'available_date' => '0000-00-00',
'vend_id' => null,
'id_shop' => '1',
'id_attribute_group' => '1',
'is_color_group' => '1',
'group_name' => 'Color',
'attribute_name' => 'Red',
'id_attribute' => '21',
),
);
$ids = array();
foreach ($array as $combinations) {
$ids['sku'] = 'sku';
$ids['variant_option_one_name'] = $combinations['group_name'];
$ids['variant_option_one_value'] = $combinations['attribute_name'];
}
print_r($ids);//
Here i am getting
Array
(
[sku] => sku
[variant_option_one_name] => Color
[variant_option_one_value] => Red
)
The above output i am getting. Seems like data is overwrite
Any correction to get both the data ?
I do not get both the colors in array. It
Thankyou
You're absolutely right, the values are being overwritten each time.
What you need to do is, each time you loop you should create a new array containing your values, and then assign that array to a new index inside the main array (so you get an array of arrays, like the expected output you've shown):
foreach ($array as $combinations) {
$arr = array();
$arr['sku'] = 'sku';
$arr['variant_option_one_name'] = $combinations['group_name'];
$arr['variant_option_one_value'] = $combinations['attribute_name'];
$ids[] = $arr;
}
Live Demo: http://sandbox.onlinephpfunctions.com/code/3a0cf7f8cbb994ef4192c1e23493bef397785937
foreach ($array as $combinations) {
array_push ($ids, [
'sku' => 'sku',
'variant_option_one_name' => $combinations['group_name'],
'variant_option_one_value' => $combinations['attribute_name']
]);
}
$array1 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'name' => 'Plate 1'
),
[1] => array(
'id' => 'xyz6378399sjwui39',
'name' => 'Plate 2'
),
[2] => array(
'id' => 'tr2e6378399sjwui39',
'name' => 'Plate 3'
)
)
and another array
$array2 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'ETA' => '8'
),
[1] => array(
'id' => 'tr2e6378399sjwui39',
'ETA' => '9'
)
[2] => array(
'id' => 'xyz6378399sjwui39',
'ETA' => '5'
)
)
I want to compare the two arrays. I am doing it like this way:-
if(!empty($array2))
{
foreach($array1 as $ck => $cl)
{
foreach($array12 as $ued){
if($cl['id'] == $ued['id'])
{
$array1[$ck]['ETA'] = $ued['ETA'];
break;
}
}
}
What are the other better ways to do this? The order of the two arrays may vary, and so does the size.
If you index the second array by the id (using array_column()) you can get away without using the inner foreach() and just use isset()...
$match = array_column($array2, null, 'id');
foreach ( $array1 as $ck=>$cl) {
if ( isset($match[$cl['id']]) ) {
$array1[$ck]['ETA'] = $match[$cl['id']]['ETA'];
}
}
print_r($array1);
I have an array and I'm trying to count the number of objects in the array where the the object key 'Value' is not 0.
array (
0 =>
array (
'name' => 'item[110189]',
'value' => '0',
'primary_key' => '110189',
),
1 =>
array (
'name' => 'item[110190]',
'value' => '50',
'primary_key' => '110190',
),
2 =>
array (
'name' => 'item[110191]',
'value' => '0',
'primary_key' => '110191',
),
3 =>
array (
'name' => 'item[110192]',
'value' => '0',
'primary_key' => '110192',
),
)
I've tried the following:
$input_items = array_filter($request->items, function($item){
$count = 0;
foreach($item as $i){
if(! $i['value'] == 0){
$count = $count + 1;
}
}
return $count;
}); // it will return an array
return $input_items;
I get an error saying invalid object 'Value' which to be honest I half expected.
Changed it this way:
$input_items = array_filter($arr, function ($item) {
return ($item['value'] != 0);
});
Full Code
<?php
$arr = array (
0 =>
array (
'name' => 'item[110189]',
'value' => '0',
'primary_key' => '110189',
),
1 =>
array (
'name' => 'item[110190]',
'value' => '50',
'primary_key' => '110190',
),
2 =>
array (
'name' => 'item[110191]',
'value' => '0',
'primary_key' => '110191',
),
3 =>
array (
'name' => 'item[110192]',
'value' => '0',
'primary_key' => '110192',
),
);
$input_items = array_filter($arr, function ($item) {
return ($item['value'] != 0);
});
print_r($input_items);
Output has only the non-zero entries:
Array
(
[1] => Array
(
[name] => item[110190]
[value] => 50
[primary_key] => 110190
)
)
Demo: http://ideone.com/LUbMSb
You can use array_reduce:
print array_reduce($request->items, function($carry ,$item){
if($item['value'] != 0){
$carry++;
}
return $carry;
},0);
In PHP, how can I compare two array and get result in a third array ?
This result must contain old and new values. The goal is to display an HTML table with a header like "field | old value | new value" as this, the user can compare all values one by one.
First array :
$array1 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
Second array :
$array2 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
What I expect :
$results = array(
'key1' => array(
'key1.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key1.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key2' => array(
'key2.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key2.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key3' => array(
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value')
),
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value'),
)
),
);
What I have already tried without success :
function array_diff_assoc_recursive($array1, $array2) {
$exclude = array(
'custom_key'
);
$difference = array();
foreach($array1 as $key => $value) {
if(is_array($value)){
if( !isset($array2[$key]) || !is_array($array2[$key]) ) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
} else {
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if(!empty($new_diff))
$difference[$key] = $new_diff;
}
} else if(!array_key_exists($key,$array2) || $array2[$key] !== $value) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
}
}
return $difference;
}
try this code, i'm sure this will work for you
<?php
echo "<pre>";
$array1 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'xxx',
'key1.3' => 'vvv',
),
'key2' => array(
'key2.1' => 'eee',
'key2.2' => 'fff',
'key2.3' => 'ggg',
),
) ;
echo "Array 1: </br>";
print_r($array1);
$array2 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'ddd',
'key1.3' => 'ccc',
),
'key2' => array(
'key2.1' => 'hhh',
'key2.2' => 'fff',
'key2.3' => 'ttt',
),
);
echo "Array 2:</br>";
print_r($array2);
$result='';
foreach($array1 as $key=> $val)
{
foreach($val as $k=> $v)
{
if($v != $array2[$key][$k])
{
$result[$key][$k]['old']= $array2[$key][$k] ;
$result[$key][$k]['new']= $v;
}
}
}
echo "Compared Result: </br>";
echo "<pre>"; print_r($result);
?>
This will Output
Array 1:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => xxx
[key1.3] => vvv
)
[key2] => Array
(
[key2.1] => eee
[key2.2] => fff
[key2.3] => ggg
)
)
Array 2:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => ddd
[key1.3] => ccc
)
[key2] => Array
(
[key2.1] => hhh
[key2.2] => fff
[key2.3] => ttt
)
)
Compared Result:
Array
(
[key1] => Array
(
[key1.2] => Array
(
[old] => ddd
[new] => xxx
)
[key1.3] => Array
(
[old] => ccc
[new] => vvv
)
)
[key2] => Array
(
[key2.1] => Array
(
[old] => hhh
[new] => eee
)
[key2.3] => Array
(
[old] => ttt
[new] => ggg
)
)
)
Prepare arrays using array_walk_recursive, and combine them. Please note that the original arrays will be changed
array_walk_recursive($array1, function(&$i) { if(!is_array($i)) $i = array('old'=> $i); });
array_walk_recursive($array2, function(&$i) { if(!is_array($i)) $i = array('new'=> $i); });
print_r(array_merge_recursive($array1, $array2));
demo
i faced with problem and i hope that you can help
I have array like this (but with hundreds of subarrays):
Array
(
[0] => Array
(
[id] => 211
[name] => Name
[description] => Desc
[Link] => http://link/211
[previewUrl] => https://link/id885364?mt=8
[payout] => 0.30
[image] => http://link/ios.png
[categories] => Array
(
[0] => iOS
[1] => Games
)
)
[1] => Array
(
[id] => 2
[name] => Name
[description] => Desc
[Link] => http://link/211
[previewUrl] => https://link/id885364?mt=8
[payout] => 2
[image] => http://link/ios.png
[categories] => Array
(
[0] => iOS
[1] => Games
)
)
)
I need to find all subarrays that equals by 'previewUrl' and then find among them one with max value of 'payout' and delete others with smaller value.
Thank you!
Loop through the original array ($arr) collecting the maximum payout values in a temporary array ($max_arr). When a higher payout is found replace the previous higher payout in the temporary array and delete it in the original array. When a lower or equal payout is found delete it.
<?php
$arr = array(array('id' => 211, 'name' => 'Name', 'description' => 'Desc', 'Link' => 'http://link/211', 'previewUrl' => 'https://link/id885364?mt=8', 'payout' => '0.30', 'image' => 'http://link/ios.png', 'categories' => array('0' => 'iOS', '1' => 'Games')), array('id' => 2, 'name' => 'Name', 'description' => 'Desc', 'Link' => 'http://link/211', 'previewUrl' => 'https://link/id885364?mt=8', 'payout' => '2', 'image' => 'http://link/ios.png', 'categories' => array('0' => 'iOS', '1' => 'Games')), array('id' => 11, 'name' => 'Name', 'description' => 'Desc', 'Link' => 'http://link/211', 'previewUrl' => 'https://link/id885364?mt=7', 'payout' => '3', 'image' => 'http://link/ios.png', 'categories' => array('0' => 'iOS', '1' => 'Games')), array('id' => 1, 'name' => 'Name', 'description' => 'Desc', 'Link' => 'http://link/211', 'previewUrl' => 'https://link/id885364?mt=7', 'payout' => '1', 'image' => 'http://link/ios.png', 'categories' => array('0' => 'iOS', '1' => 'Games')));
$max_arr = array(); // temporary array
foreach ( $arr as $key => $value ) {
if ( !isset($max_arr[$value['previewUrl']]) ) {
$max_arr[$value['previewUrl']] = array_merge(array('key' => $key), $value);
}
else {
// higher payout
if ( $max_arr[$value['previewUrl']]['payout'] < $value['payout'] ) {
unset($arr[$max_arr[$value['previewUrl']]['key']]);
$max_arr[$value['previewUrl']] = array_merge(array('key' => $key), $value);
}
else { unset($arr[$key]); } // lower or equal payout
}
}
?>
You can try with the following:
class MyArrayParser{
var $preview_url;
var $max_payout;
function filter_preview_url($subarray)
{
return $subarray["previewUrl"] == $this->preview_url;
}
function filter_payout($subarray)
{
return $subarray["payout"] == $this->max_payout;
}
function search_max_payout_by_previewUrl($big_array,$preview_url)
{
$this->preview_url = $preview_url;
$filtered_array = array_filter($big_array,array($this,"filter_preview_url")); //Only subarrays with previewUrl == $preview_url
function payout_extract($subarray)
{
return $subarray["payout"];
}
$payouts_list = array_map("payout_extract",$filtered_array);
if(count($payouts_list)==0) //PreviewUrl not found
return array();
$this->max_payout = max($payouts_list);
$only_max_payout_list = array_filter($filtered_array,array($this,"filter_payout"));
return $only_max_payout_list;
}
}
$obj = new MyArrayParser();
$filtered_array = $obj->search_max_payout_by_previewUrl($my_big_array,"....previewUrl...."));
Not necessarily fast, but it's pretty easy to understand.
$a = array(
array ('id' => 211,'previewUrl' => 'https://link/id885364?mt=8','payout' => 0.30),
array ('id' => 2,'previewUrl' => 'https://link/id885364?mt=8','payout' => 2));
$searchUrl = 'https://link/id885364?mt=8';
$to_delete = array();
$max_payout = -1;
$max_key = "";
// Loop through array, looking at previewUrls that match.
foreach ($a as $key => $subarray) {
if ($subarray['previewUrl'] == $searchUrl) {
// Save all matches to an array for deletion.
array_push($to_delete, $key);
// Find the element with the highest payout.
if ($subarray['payout'] > $max_payout || $max_payout == -1) {
$max_payout = $subarray['payout'];
$max_key = $key;
}
}
}
// Remove the element with the highest payout.
if (($key = array_search($max_key, $to_delete)) !== false) {
unset($to_delete[$key]);
}
//print $max_payout;
//print $max_key;
//print_r($to_delete);
// Finally, delete all the elements flagged for deletion.
foreach ($to_delete as $key) {
unset($a[$key]);
}
print_r($a);