Multidimensional array remove inner array key based on condition - php

I have a array which i want to remove the first and second array from the array since status
is blank for first and second array .
The output should be
array([0]=> array (
[A] => 300000
[B] => jill
[status]=> "something"
)
)
any ideas to proceed?
array(
[0] => Array
(
[A] => 100000
[B] => jjohn
[status]=>
)
[1] => Array
(
[A] => 200000
[B] => jim
[status]=>
)
[2] => Array
(
[A] => 300000
[B] => jill
[status]=> "something"
)
)

$array = array_filter($array, function (array $i) { return $i['status']; });

This function checks if (bool)$item['status'] is evaluated as True, except
string '0'.
Function:
function ($item) {
return isset($item['status']) && ($item['status'] || is_string($item['status']));
}
Test Code:
$array = array(
array(
'Name' => 'Empty String',
'status' => '',
),
array(
'Name' => 'String Zero',
'status' => '0',
),
array(
'Name' => 'Integer Zero',
'status' => 0,
),
array(
'Name' => 'Bool False',
'status' => false,
),
array(
'Name' => 'NULL',
'status' => null,
),
array(
'Name' => 'Undefined',
),
);
$array = array_values(array_filter($array, function ($item) {
return isset($item['status']) && ($item['status'] || is_string($item['status']));
}));
var_dump($array);
Result:
array(1) {
[0]=>
array(2) {
["Name"]=>
string(11) "String Zero"
["status"]=>
string(1) "0"
}
}

Related

Transform multiple values to single key

I am using php 7.1 and I have the following array:
<?php
$arr = array (
0 =>
array (
'Product' => 'Product1',
'Exact_Match_Keyword' => 'apples freshness',
),
1 =>
array (
'Product' => 'Product1',
'Exact_Match_Keyword' => 'apples',
),
2 =>
array (
'Product' => 'Product1',
'Exact_Match_Keyword' => 'oranges',
),
3 =>
array (
'Product' => 'Product2',
'Exact_Match_Keyword' => 'apples freshness',
),
4 =>
array (
'Product' => 'Product2',
'Exact_Match_Keyword' => 'apples',
),
);
$arr = array_merge_recursive($arr);
var_dump($arr);
/* WANTED DATA STRUCTURE
$arr = array (
0 =>
array (
'Product' => 'Product1',
'Exact_Match_Keyword' => array('apples freshness', 'apples', 'oranges'),
),
1 =>
array (
'Product' => 'Product2',
'Exact_Match_Keyword' => array('apples freshness', 'apples'),
),
);
*/
I tried to use array_merge_recursive however this does not give me my wanted data structure.
Any suggestions what I am doing wrong?
I appreciate your replies!
You can use array_reduce to handle simple logic like this for you. The example below will provide you with the expected format you've posted.
$example = array_values(
array_reduce(
$arr,
static function ($acc, $row) {
if (!isset($acc[$row['Product']])) {
$acc[$row['Product']] = [
'Product' => $row['Product'],
'Exact_Match_Keyword' => [$row['Exact_Match_Keyword']],
];
} else {
$acc[$row['Product']]['Exact_Match_Keyword'] = array_merge(
$acc[$row['Product']]['Exact_Match_Keyword'],
[$row['Exact_Match_Keyword']]
);
}
return $acc;
}
));
print_r($example);
It can be simplified further if the format you expect is flexible:
$example = array_reduce(
$arr,
static function ($acc, $row) {
if (!isset($acc[$row['Product']])) {
$acc[$row['Product']] = [$row['Exact_Match_Keyword']];
} else {
$acc[$row['Product']] = array_merge(
$acc[$row['Product']],
[$row['Exact_Match_Keyword']]
);
}
return $acc;
}
);
print_r($example);
//Output:
//[
// 'Product1'=> ['apples freshness', 'apples', 'oranges'],
// 'Product2'=> ['apples freshness', 'apples']
//]
I think this gets you what you want. Probably not the most graceful thing in the world but it's roughly the logic you'd want to follow.
$temp = [];
foreach ($arr as $v)
{
$pname = $v['Product'];
if (!isset($temp[$pname]))
{
$temp[$pname] = [];
}
$temp[$pname][] = $v['Exact_Match_Keyword'];
}
$out = [];
foreach ($temp as $k => $v)
{
$out[] = [
'Product' => $k,
'Exact_Match_Name' => $v
];
}
php > var_dump($out);
php shell code:1:
array(2) {
[0] =>
array(2) {
'Product' =>
string(8) "Product1"
'Exact_Match_Name' =>
array(3) {
[0] =>
string(16) "apples freshness"
[1] =>
string(6) "apples"
[2] =>
string(7) "oranges"
}
}
[1] =>
array(2) {
'Product' =>
string(8) "Product2"
'Exact_Match_Name' =>
array(2) {
[0] =>
string(16) "apples freshness"
[1] =>
string(6) "apples"
}
}
}
For future reference, if you would like to use the array_merge_recursive() approach on its own, the input data might have to be a little different from what I can tell.
After looking at the example in the documentation page for array_merge_recursive(), I wonder if the original input data needs to be structured a little differently. I think there needs to be matching inner array keys in order for the final array to have something to combine on for the various inner keys. In the example data below, I used the Products key to combine on for the first inner key.
I don't know if it's possible for your starting data to be structured differently for this process, but if the data could look like the following (based on the example on the documentation page for array_merge_recursive()):
<?php
$ar1 = array(
"Products" => array(
"Product1" => array(
"Exact_Match_Keyword" => array('apples freshness')
)
)
);
$ar2 = array(
"Products" => array(
"Product1" => array(
"Exact_Match_Keyword" => array('apples')
)
)
);
$ar3 = array(
"Products" => array(
"Product1" => array(
"Exact_Match_Keyword" => array('oranges')
)
)
);
$ar4 = array(
"Products" => array(
"Product2" => array(
"Exact_Match_Keyword" => array('apples freshness')
)
)
);
$ar5 = array(
"Products" => array(
"Product2" => array(
"Exact_Match_Keyword" => array('apples')
)
)
);
$result = array_merge_recursive($ar1, $ar2, $ar3, $ar4, $ar5);
print_r($result);
The output should then look like this:
Array
(
[Products] => Array
(
[Product1] => Array
(
[Exact_Match_Keyword] => Array
(
[0] => apples freshness
[1] => apples
[2] => oranges
)
)
[Product2] => Array
(
[Exact_Match_Keyword] => Array
(
[0] => apples freshness
[1] => apples
)
)
)
)

Grouped Array data

I'm trying to figure out how to get data from the following data structure. I managed to group a flat array into the following array, but am finding it difficult to find the proper resources to explain how to get the data out. I'm looking to get the count of the items in each group. Then i'd like to print the ids from the inner array...
array (
'grinds' =>
array (
0 =>
array (
'id' => 16562,
'slug' => 'grinds',
),
1 =>
array (
'id' => 16561,
'slug' => 'grinds',
),
),
'online-grinds' =>
array (
0 =>
array (
'id' => 16566,
'slug' => 'online-grinds',
),
),
)
$my_array1 = array(
'grinds' =>
array(
0 =>
array(
'id' => 16562,
'slug' => 'grinds',
),
1 =>
array(
'id' => 16561,
'slug' => 'grinds',
),
),
'online-grinds' =>
array(
0 =>
array(
'id' => 16566,
'slug' => 'online-grinds',
),
),
);
get counts:
$counts = array();
foreach ($my_array1 as $key => $val) {
$counts[$key] = count($val);
}
var_dump($counts);
yields:
array(2) {
["grinds"]=>
int(2)
["online-grinds"]=>
int(1)
}
get inner ids:
$innerids = array();
foreach ($my_array1 as $key => $val) {
foreach ($val as $key2 => $val2) {
$innerids[] = $val2['id'];
}
}
var_dump($innerids);
yields:
array(3) {
[0]=>
int(16562)
[1]=>
int(16561)
[2]=>
int(16566)
}
You could use array_map and then for every item use array_column and specifing the field name and then use array_count_values to count the unique values.
Then combine those in an array and use the existing key again as the key for then new array.
$arrays = array_map(function($x) {
return [
array_count_values(array_column($x, 'id')),
array_count_values(array_column($x, 'slug'))
];
}, $arrays);
print_r($arrays);
Result
Array
(
[grinds] => Array
(
[0] => Array
(
[16562] => 1
[16561] => 1
)
[1] => Array
(
[grinds] => 2
)
)
[online-grinds] => Array
(
[0] => Array
(
[16566] => 1
)
[1] => Array
(
[online-grinds] => 1
)
)
)
Demo

PHP : merge multi arrays in sections

I load data from .xlsx sheet
And i convert it to two arrays
The first is the header columns
The second is the data columns
I did this
$c = array_combine($headers, $data);
when i print $c
Array
(
[id] => Array
(
[0] => 1
[1] => 2
)
[f-name] => Array
(
[0] => Mohammed
[1] => Ziad
)
[s-name] => Array
(
[0] => Amer
[1] => Mohammed
)
[t-name] => Array
(
[0] => Hendy
[1] => Shokry
)
[cid] => Array
(
[0] => 89
[1] => 55
)
)
i want to make the result like that
array(
[0] => Array(
[id] => 0
[f-name] => mohammed
[s-name] => amer
[t-name] => hendy
[cid] => 89
)
[1] => Array(
[id] => 1
[f-name] => ziad
[s-name] => mohammed
[t-name] => shokry
[cid] => 55
)
)
try this:
$data = array(
'id' => array
(
0 => 1,
1 => 2
),
'f-name' => array
(
0 => 'Mohammed',
1 => 'Ziad'
),
's-name' => array
(
0 => 'Amer',
1 => 'Mohammed'
),
't-name' => array
(
0 => 'Hendy',
1 => 'Shokry'
),
'cid' => array
(
0 => 89,
1 => 55
)
);
//
$result = array();
foreach($data as $k=>$v){
for($i=0;$i<count($data['id']);$i++){
//$v[$i] = ($k!='id') ?: $i;// uncomment for reset id from 0
$result[$i][$k] = $v[$i];
}
}
var_dump($result);
result:
array (size=2)
0 =>
array (size=5)
'id' => int 1
'f-name' => string 'Mohammed' (length=8)
's-name' => string 'Amer' (length=4)
't-name' => string 'Hendy' (length=5)
'cid' => int 89
1 =>
array (size=5)
'id' => int 2
'f-name' => string 'Ziad' (length=4)
's-name' => string 'Mohammed' (length=8)
't-name' => string 'Shokry' (length=6)
'cid' => int 55
Try something like this:
for ($index = 0; &index < 2; ++$index)
{
thing['id'] = $index;
thing['f-name'] = $c['f-name'];
thing['l-name'] = $c['s-name'];
thing['t-name'] = $c['t-name'];
thing['cid'] = $c['cid'];
$newArra y[$index] = thing;
}
I like to include "fancy" array functions like array_walk and array_map whenever I have the chance:
Initialize your data
$data = [
'id' => [
0 => 1,
1 => 2
],
'f-name' => [
0 => 'Mohammed',
1 => 'Ziad'
],
's-name' => [
0 => 'Amer',
1 => 'Mohammed'
],
't-name' => [
0 => 'Hendy',
1 => 'Shokry'
],
'cid' => [
0 => 89,
1 => 55
]
];
Transform the data
$result = [];
array_walk($data['id'],
function($f, $i) use ($data, &$result){
$result[$i] = array_map(function($e) use ($i){
return $e[$i];
}, $data);
}
);
Output the result
var_dump($result);
array(2) {
[0]=>
array(5) {
["id"]=>
int(1)
["f-name"]=>
string(8) "Mohammed"
["s-name"]=>
string(4) "Amer"
["t-name"]=>
string(5) "Hendy"
["cid"]=>
int(89)
}
[1]=>
array(5) {
["id"]=>
int(2)
["f-name"]=>
string(4) "Ziad"
["s-name"]=>
string(8) "Mohammed"
["t-name"]=>
string(6) "Shokry"
["cid"]=>
int(55)
}
}

how to sort just a part from a multidimensional array? [duplicate]

This question already has answers here:
How to Sort a Multi-dimensional Array by Value
(16 answers)
Closed 7 years ago.
i have a multiple array.. the output looks like this:
Array
(
[0] => Array
(
[0] => AdsBot
[1] => 7
)
[1] => Array
(
[0] => SurveyBot
[1] => 1
)
[2] => Array
(
[0] => bingbot
[1] => 3
)
[3] => Array
(
[0] => bot
[1] => 27
)
what i need now is to sort arrays by there number.. so it should look exactly like this:
Array
(
[0] => Array
(
[0] => bot
[1] => 27
)
[1] => Array
(
[0] => AdsBot
[1] => 7
)
[2] => Array
(
[0] => bingbot
[1] => 3
)
[3] => Array
(
[0] => SurveyBot
[1] => 1
)
i need to sort it by the numbers array key.. but i really dont know how- well, i'm new to php
the multi. array code :
$bot_array = [
['name' => 'bingbot', 'number' => $bingbot],
['name' => 'googlebot', 'number' => $googlebot],
['name' => 'robots.txt', 'number' => $robots_txt],
['name' => 'exabot', 'number' => $exabot],
['name' => 'bot', 'number' => $bot],
['name' => 'robot', 'number' => $robot],
['name' => 'BaiDuSpider', 'number' => $BaiDuSpider],
['name' => 'Yahoo Slurp', 'number' => $yahoo_slurp],
['name' => 'AdsBot', 'number' => $adsbot],
['name' => 'SurveyBot', 'number' => $surveybot],
['name' => 'scanner', 'number' => $scanner],
['name' => 'checker', 'number' => $checker],
];
or maybe there is a more smarter way to do this?
i need this for a top ten :) on the left should be written all the names and at the right the quantity
thanks for any help :)
EDIT:
$tmp = Array();
foreach($bot_array as &$ba)
$tmp[] = &$ba["number"];
array_multisort($tmp, $bot_array);
foreach($bot_array as &$ba)
echo $ba["number"]."<br/>";
i did this but it still doesnt sort it like i want it..
0
0
0
1
10
12
27
3
3
5
7
9
this is what it gives me now :o
you can use this function
function sortAscending($accounts, $key)
{
$ascending = function($accountA, $accountB) use ($key) {
if ($accountA[$key] == $accountB[$key]) {
return 0;
}
return ($accountA[$key] < $accountB[$key]) ? -1 : 1;
};
usort($accounts, $ascending);
return $accounts;
}
You can use usort
<?php
$data = array(
array('AdsBot', 7),
array('SurveyBot', 1),
array('bingbot', 3),
array('bot', 27)
);
usort($data, 'botSort');
function botSort($val1, $val2) {
if (is_array($val1) && is_array($val2)) {
if ($val1[1] <= $val2[1]) {
return 1;
}
}
return -1;
}
var_dump($data);
Output
array(4) {
[0] =>
array(2) {
[0] =>
string(3) "bot"
[1] =>
int(27)
}
[1] =>
array(2) {
[0] =>
string(6) "AdsBot"
[1] =>
int(7)
}
[2] =>
array(2) {
[0] =>
string(7) "bingbot"
[1] =>
int(3)
}
[3] =>
array(2) {
[0] =>
string(9) "SurveyBot"
[1] =>
int(1)
}
}
According to your updated question, it should be.
<?php
usort($bot_array, 'botSort');
function botSort($val1, $val2) {
if (is_array($val1) && is_array($val2)) {
if ($val1['number'] <= $val2['number']) {
return 1;
}
}
return -1;
}
print_r($data);
Use this way to sort your array
$arry = array( array('AdsBot','7'),
array('SurveyBot','1'),
array('bingbot','3'),
array('bot','27')
);
echo "<pre>"; print_r($arry); echo "</pre>";
function sortByOrder($a, $b) {
return $a['1'] - $b['1'];
}
usort($arry, 'sortByOrder');
echo "<pre>"; print_r($arry); echo "</pre>";
Please, see bellow code.
$arr = array(
0 => array(
'0' => 'AdsBot',
'1' => 7
),
1 => array(
'0' => 'SurveyBot',
'1' => 1
),
2 => array(
'0' => 'bingbot',
'1' => 3
),
3 => array(
'0' => 'bot',
'1' => 27
)
);
echo '<pre>';
print_r(sortDescOrder($arr,'1'));
echo '</pre>';
function sortDescOrder($accounts, $key)
{
$ascending = function($accountA, $accountB) use ($key) {
if ($accountA[$key] == $accountB[$key]) {
return 0;
}
return ($accountA[$key] > $accountB[$key]) ? -1 : 1;
};
usort($accounts, $ascending);
return $accounts;
}
Or see another code
$bot_array = [
['name' => 'bingbot', 'number' => 5],
['name' => 'googlebot', 'number' => 8],
['name' => 'robots.txt', 'number' => 3],
['name' => 'exabot', 'number' => 7],
['name' => 'bot', 'number' => 7],
['name' => 'robot', 'number' => 12],
['name' => 'BaiDuSpider', 'number' => 45],
['name' => 'Yahoo Slurp', 'number' => 18],
['name' => 'AdsBot', 'number' => 78],
['name' => 'SurveyBot', 'number' => 96],
['name' => 'scanner', 'number' => 41],
['name' => 'checker', 'number' => 10]
];
usort($bot_array, function($x, $y) {
return $x['number'] <= $y['number'];
});
echo '<pre>';
print_r($bot_array);
echo '</pre>';
Try usort(). It allows you to define a callback to sort on a custom expression. In your case you want to reverse sort by the second indexed element in each sub-array:
<?php
$bots = [
[
'name' => 'AdsBot',
'number' => 7,
],
[
'name' => 'SurveyBot',
'number' => 1,
],
[
'name' => 'bingbot',
'number' => 3,
],
[
'name' => 'bot',
'number' => 27,
],
];
usort($bots, function($a, $b) {
return $a['number'] <= $b['number'];
});
print_r($bots);
Yields:
Array
(
[0] => Array
(
[name] => bot
[number] => 27
)
[1] => Array
(
[name] => AdsBot
[number] => 7
)
[2] => Array
(
[name] => bingbot
[number] => 3
)
[3] => Array
(
[name] => SurveyBot
[number] => 1
)
)
Hope this helps :)

PHP multi-dimentional array condensing

I am using an array like this for a static file cache:
[
key => data => [
key1 => data => [...]
=> expires => 123456
key2 => data => [...]
=> expires => 123456
]
=> expires => 123456
]
This can be many levels deep (sometimes 10-15 levels).
What I would like to do is return only the values of data, so for instance, to create an array like so
[
key => key1 => [...]
=> key2 => [...]
]
how would I do this?
EDIT
print_r of the structure
Array (
[key] =>
Array (
[data] =>
Array (
[key1] =>
Array (
[data] => Array ( ... )
[expires] => 12345678)
[key2] =>
Array (
[data] => Array ( ... )
[expires] => 12345678
)
)
[expires] => 12345678
)
)
You can use recursive function like this:
function extractValues($array, &$result){
foreach($array as $key1 => $val1){
if($key1 == 'data' && is_array($val1)) {
foreach($val1 as $key2 => $val2){
if(is_array($val2)) {
$result[$key2] = array();
extractValues($val2, $result[$key2]);
} else {
$result[$key2] = $val2;
}
}
} else if(!in_array($key1, array('expires'))) {
$result[$key1] = array();
extractValues($val1, $result[$key1]);
}
}
return $result;
}
It will work on array structure like this:
$test = array(
'key' => array(
'data' => array(
'key1' => array(
'data' => array(
'key11' => 11,
'key12' => 12,
),
),
'key2' => array(
'data' => array(
'key21' => 21,
'key22' => 22,
),
),
),
'expires' => 12345,
),
);
$result = array();
extractValues($test, $result);
var_dump($result);
This is the result of the var_dump() hope meets your requirement:
array(1) {
["key"]=>
array(2) {
["key1"]=>
array(2) {
["key11"]=>
int(11)
["key12"]=>
int(12)
}
["key2"]=>
array(2) {
["key21"]=>
int(21)
["key22"]=>
int(22)
}
}
}

Categories