Find similar subarrays in some arrays - php

Have some arrays:
$a = array(
0 => array('value' => 1000, 'name' => 'AA1'),
1 => array('value' => 2000, 'name' => 'AA2'),
2 => array('value' => 3000, 'name' => 'AA3'),
3 => array('value' => 4000, 'name' => 'AA4'),
);
$b = array(
0 => array('value' => 1000, 'name' => 'BB1'),
1 => array('value' => 3000, 'name' => 'BB2'),
2 => array('value' => 1700, 'name' => 'BB3'),
3 => array('value' => 1200, 'name' => 'BB4'),
);
$c = array(
0 => array('value' => 3000, 'name' => 'CC1'),
1 => array('value' => 4000, 'name' => 'CC2'),
2 => array('value' => 4300, 'name' => 'CC3'),
3 => array('value' => 5000, 'name' => 'CC4'),
);
How can create a new array with the same variants from arrays $a, $b and $c? And order it by 'value' field..
$d = array(
0 => array('value' => 3000, 'name' => 'AA3');
);
Real example: http://3v4l.org/MAWjd

// Test Data
$timeVariantSerialized = 'a:3:{s:7:"group_a";a:3:{i:0;a:3:{s:10:"id_variant";i:122;s:4:"name";s:13:"3 hour 30 min";s:4:"time";i:12600;}i:1;a:3:{s:10:"id_variant";i:173;s:4:"name";s:6:"3 hour";s:4:"time";i:10800;}i:2;a:3:{s:10:"id_variant";i:271;s:4:"name";s:6:"1 hour";s:4:"time";i:3600;}}s:7:"group_b";a:2:{i:0;a:3:{s:10:"id_variant";i:107;s:4:"name";s:13:"1 hour 30 min";s:4:"time";i:5400;}i:1;a:3:{s:10:"id_variant";i:321;s:4:"name";s:6:"3 hour";s:4:"time";i:10800;}}s:7:"group_c";a:4:{i:0;a:3:{s:10:"id_variant";i:28;s:4:"name";s:6:"1 hour";s:4:"time";i:3600;}i:1;a:3:{s:10:"id_variant";i:98;s:4:"name";s:6:"3 hour";s:4:"time";i:10800;}i:2;a:3:{s:10:"id_variant";i:157;s:4:"name";s:6:"2 hour";s:4:"time";i:7200;}i:3;a:3:{s:10:"id_variant";i:158;s:4:"name";s:13:"1 hour 30 min";s:4:"time";i:5400;}}}';
// Test Data Array
$time_variant = unserialize( $timeVariantSerialized );
$groupsCount = count( $time_variant );
foreach( $time_variant as $groupId => $groupArray )
{
foreach( $groupArray as $groupChildId => $groupChildArray )
{
$timeCountsArray[$groupChildArray['time']][$groupId] = $groupChildId;
}
}
$result = array();
foreach( $timeCountsArray as $time => $groupIdsArray )
{
if( $groupsCount > count( $groupIdsArray ) ) continue;
foreach( $groupIdsArray as $groupId => $groupChildId )
{
$result[$time_variant[$groupId][$groupChildId]['id_variant']]
= $time_variant[$groupId][$groupChildId];
// If you need only one result , uncomment the below break
// break;
}
// If more than 1 time could have variants , comment out below break to get them all
break;
}
ksort( $result );
print_r( $result );
Result Array :
array
(
'98' => array
(
'id_variant' => 98
'name' => 3 hour
'time' => 10800
)
'173' => array
(
'id_variant' => 173
'name' => 3 hour
'time' => 10800
)
'321' => array
(
'id_variant' => 321
'name' => 3 hour
'time' => 10800
)
)

I'm not sure if this is what you want.
The result is a single array with all the repeated values in the given arrays:
//Lets merge them into a big array to work in a easier way;
//It will be a single level array as follow: [a0] => 1000, [a1] => 2000 etc.
$array = array('a' => $a, 'b' => $b, 'c' =>$c);
foreach($array as $letter => $subArray){
foreach($subArray as $key => $values){
$newArray[$letter.$key] = $values['value'];
}
}
$uniques = array_unique($newArray); //getting the non-repeated values
$repeated = array_diff_assoc($newArray, $uniques); // stripping them out
$final = array_unique($repeated); //cleaning the repeated values to just 1 of each
print_r($final);
Result
Array
(
[b0] => 1000
[b1] => 3000
[c1] => 4000
)

Related

Sum array values by attribute name

I want to sum count values with same code.
This is my array:
$data = array(
array(
'code' => 02,
'count' => 8
),
array(
'code' => 03,
'count' => 1
),
array(
'code' => 03,
'count' => 1
),
array(
'code' => 03,
'count' => 7
),
array(
'code' => 11,
'count' => 1
),
array(
'code' => 11,
'count' => 5
),
array(
'code' => 17,
'count' => 4
),
array(
'code' => 17,
'count' => 2
),
array(
'code' => 17,
'count' => 8
)
);
Now I tried to group the array to sum the count with same code, but I think I'm wrong:
$new_data = [];
foreach($data as $k => $v){
$total = 0;
$new_data[$v['code']] = array(
'ttl' => $v['count'] + $total,
);
}
echo '<pre>';
print_r($new_data);
echo '</pre>';
What is the correct code for this? Thanks.
using isset will avoid undefined offset error:
$new_data = [];
foreach($data as $k => $v){
if (!isset($new_data[$v['code']]['ttl'])){
$new_data[$v['code']]['ttl'] = 0;
}
$new_data[$v['code']]['ttl'] += $v['count'];
}
print_r($new_data);
Assuming you want the keys in $new_data to to be the unique codes, and the values to be an an array with a key of ttl whose value is the sum of the counts for that particular code:
$new_data = [];
foreach($data as $v){
if (!array_key_exists($v['code'], $new_data)) {
$new_data[$v['code']]['ttl'] = $v['count'];
} else {
$new_data[$v['code']]['ttl'] += $v['count'];
}
}
I think this is what you want as output:
Array
(
[2] => Array
(
[ttl] => 8
)
[3] => Array
(
[ttl] => 9
)
[11] => Array
(
[ttl] => 6
)
[17] => Array
(
[ttl] => 14
)
)
If so, you can do minor modifications to your code such as this:
$new_data = [];
foreach ($data as $d) {
if (isset($new_data[$d['code']]['ttl'])) {
$new_data[$d['code']]['ttl'] += $d['count'];
} else {
$new_data[$d['code']]['ttl'] = $d['count'];
}
}

Count number of values in an array where not 0

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);

remove duplicate values from multidimensional array by single value

Ok the thing is, Ive read and tried a lot of solutions found here based on complete duplicateness, BUT I need something a little bit different and cant figure it out...
Because I only want to get and remove the duplicate value if only 1 of the array values is duplicate.
And also later combine the two but that's not that difficult.
$a = array(
array(
'id' => 1,
'qty' => 1
),
array(
'id' => 0,
'qty' => 1
),
array(
'id' => 1,
'qty' => 2
)
);
What I want the outcome to be:
$b = array(
array(
'id' => 1,
'qty' => 3
),
array(
'id' => 0,
'qty' => 1
)
);
You can do something like the following:
<?php
$a = array(
array(
'id' => 1,
'qty' => 1
),
array(
'id' => 0,
'qty' => 1
),
array(
'id' => 1,
'qty' => 2
)
);
$idsList = array();
$res = array();
foreach ($a as $arr){
if (!in_array($arr['id'], $idsList)){
$res[$arr['id']] = $arr;
$idsList[] = $arr['id'];
}
else{
$res[$arr['id']]['qty'] += $arr['qty'];
}
}
echo "<pre>";
print_r($res);
To get array like that:
Array
(
[1] => Array
(
[id] => 1
[qty] => 3
)
[0] => Array
(
[id] => 0
[qty] => 1
)
)
Checkout This DEMO: http://codepad.org/UP0G7WnE
$a = array(
array(
'id' => 1,
'qty' => 1
),
array(
'id' => 0,
'qty' => 1
),
array(
'id' => 1,
'qty' => 2
)
);
$b = array();
$ids = array();
for($i = 0; $i < count($a); $i++)
{
if(in_array($a[$i]['id'], $ids))
{
$j = array_search($a[$i]['id'], array_values($ids));
$b[$j]['qty'] += $a[$i]['qty'];
}
else
{
$b[$i]['id'] = $a[$i]['id'];
$b[$i]['qty'] = $a[$i]['qty'];
$ids[] = $a[$i]['id'];
}
}
echo "<pre>";
print_r($b);
This could be a solution:
$temp = array();
foreach ($a as $data){
if (isset($temp[$data['id']])){
$temp[$data['id']] += $data['qty'];
} else {
$temp[$data['id']] = $data['qty'];
}
}
// Format array
$b = array();
foreach ($temp as $id => $qty){
$b[] = array(
'id' => $id,
'qty' => $qty
);
}
Output will be:
Array
(
[0] => Array
(
[id] => 1
[qty] => 3
)
[1] => Array
(
[id] => 0
[qty] => 1
)
)

Find duplicate array values and delete conditionally

I have an multidimensional array like this:
$orders = array(
array(
'id' => '123',
'name' => 'John',
'lastname'=>'Carter',
'rate' => '1.0'
),
array(
'id' => '546',
'name' => 'Ben',
'lastname'=>'Wall',
'rate' => '0.25'
),
array(
'id' => '666',
'name' => 'John Bow',
'lastname'=>'Porter',
'rate' => '0.25'
),
array(
'id' => '156',
'name' => 'John',
'lastname'=>'Carter',
'rate' => '0.5'
)
);
and want make a function that will be delete duplicate rows that rate < 1.0. The result array should be:
$orders = array(
array(
'id' => '123',
'name' => 'John',
'lastname'=>'Carter',
'rate' => '1.0'
),
array(
'id' => '546',
'name' => 'Ben',
'lastname'=>'Wall',
'rate' => '0.25'
),
array(
'id' => '666',
'name' => 'John',
'lastname'=>'Porter',
'rate' => '0.25'
)
);
Not very beautiful and speed, but workable solution:
$a = array(...); // Your array
$hashstack = array_map(function($value) { return md5($value['name'] . $value['lastname']); }, $a);
$result = array_filter($a, function($value) use ($hashstack)
{
if ((float)$value['rate'] < 1.0) {
$count = 0;
foreach ($hashstack as $hash) {
if (md5($value['name'] . $value['lastname']) == $hash) {
$count++;
}
}
if ($count > 1) {
unset($value);
return;
}
}
return $value;
});
Result is the same of yours.
Edit: Second and good version here: http://ideone.com/zJ8vj
What do You mean by 'duplicated' - same 'rate' ?
Bellow example remove duplicated orders with same 'rate' and 'rate' < 1.0.
Is this what You need ?
$tmpOrders = array();
foreach($orders as $order) {
// Check only rate < 1.0
if((float)$order['rate'] < 1.0) {
// Check duplicate
$exists = false;
foreach($tmpOrders as $tmp) {
if($tmp['rate'] == $order['rate']) {
$exists = true;
break;
}
}
// Add if rate not exists
if(!$exists) {
$tmpOrders[] = $order;
}
}
// Add all with rate >= 1.0
else {
$tmpOrders[] = $order;
}
}
$orders = $tmpOrders;
echo "<pre>";
print_r($orders);
echo "<pre>";
Result:
Array
(
[0] => Array
(
[id] => 123
[name] => John
[lastname] => Carter
[rate] => 1.0
)
[1] => Array
(
[id] => 546
[name] => Ben
[lastname] => Wall
[rate] => 0.25
)
[2] => Array
(
[id] => 156
[name] => John
[lastname] => Carter
[rate] => 0.5
)
)

Searching in a multi-dimensional array (PHP)

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));

Categories