Im having trouble extracting some information from a large array and placing it in a smaller array, the large array i have is as follows;
Array
(
[0] => Array
(
[BlanketBrand] => Array
(
[BlanketBrandID] => 125
[BlanketBrandName] => Neptune
[BlanketBrandActive] => Y
)
)
[1] => Array
(
[BlanketBrand] => Array
(
[BlanketBrandID] => 126
[BlanketBrandName] => King Size
[BlanketBrandActive] => Y
)
)
)
What i would like is to create an array from this with just the BlanketBrandID as the key and the BlanketBrandName as the value
array(
125 => Neptune,
126 => King Size
)
Something like that so its easier for me to work with.
Any help would be great.
Thanks
This can be done in a very simple foreach loop:
<?php
$array = [
[
'BlanketBrand' => [
'BlanketBrandID' => 125,
'BlanketBrandName' => 'Neptune',
'BlanketBrandActive' => 'Y'
]
],
[
'BlanketBrand' => [
'BlanketBrandID' => 126,
'BlanketBrandName' => 'King Size',
'BlanketBrandActive' => 'Y'
]
]
];
$new_array = [];
foreach ($array as $item) {
$new_array[ $item['BlanketBrand']['BlanketBrandID'] ] = $item['BlanketBrand']['BlanketBrandName'];
}
print_r($new_array);
See example here.
You can also accomplish this with array_reduce():
$new_array = array_reduce($array, function($a, $b) {
$a[ $b['BlanketBrand']['BlanketBrandID'] ] = $b['BlanketBrand']['BlanketBrandName'];
return $a;
}, []);
See example here.
Related
I have an multidimensional array and I need to count their specific value
Array
(
[0] => Array
(
[Report] => Array
(
[id] => 10
[channel] => 1
)
)
[1] => Array
(
[Report] => Array
(
[id] => 92
[channel] => 0
)
)
[2] => Array
(
[Report] => Array
(
[id] => 18
[channel] => 0
)
)
[n] => Array
)
I need to get output like that: channel_1 = 1; channel_0 = 2 etc
I made a function with foreach:
foreach ($array as $item) {
echo $item['Report']['channel'];
}
and I get: 1 0 0 ... but how can I count it like: channel_1 = 1; channel_0 = 2, channel_n = n etc?
Try this. See comments for step-by-step explanation.
Outputs:
array(2) {
["channel_1"]=>
int(1)
["channel_0"]=>
int(2)
}
Code:
<?php
// Your input array.
$a =
[
[
'Report' =>
[
'id' => 10,
'channel' => 1
]
],
[
'Report' =>
[
'id' => 92,
'channel' => 0
]
],
[
'Report' =>
[
'id' => 18,
'channel' => 0
]
]
];
// Output array will hold channel_N => count pairs
$result = [];
// Loop over all reports
foreach ($a as $report => $values)
{
// Key takes form of channel_ + channel number
$key = "channel_{$values['Report']['channel']}";
if (!isset($result[$key]))
// New? Count 1 item to start.
$result[$key] = 1;
else
// Already seen this, add one to counter.
$result[$key]++;
}
var_dump($result);
/*
Output:
array(2) {
["channel_1"]=>
int(1)
["channel_0"]=>
int(2)
}
*/
You can easily do this without a loop using array_column() and array_count_values().
$reports = array_column($array, 'Report');
$channels = array_column($reports, 'channel');
$counts = array_count_values($channels);
$counts will now equal an array where the key is the channel, and the value is the count.
Array
(
[1] => 1
[0] => 2
)
I need to take an array like this:
Array
(
[0] => Array
(
[county_code] => 54045
[count] => 218
)
[1] => Array
(
[county_code] => 54045
[count] => 115
)
[2] => Array
(
[county_code] => 54051
[count] => 79
)
)
And merge all arrays with the same county_code adding the count, like this:
Array
(
[0] => Array
(
[county_code] => 54045
[count] => 333
)
[1] => Array
(
[county_code] => 54051
[count] => 79
)
)
There will be multiple instances of multiple county codes.
Can anyone point me in the right direction?
Try this out:
// your example array
$array = [
[
"county_code" => 54045,
"count" => 218
],
[
"county_code" => 54045,
"count" => 115
],
[
"county_code" => 54051,
"count" => 79
]
];
// intrim step to collect the count.
$intrimArray = [];
foreach( $array as $data ){
$countyCode = $data["county_code"];
if (!$intrimArray[$countyCode]) {
$intrimArray[$countyCode] = $data["count"];
} else {
$intrimArray[$countyCode] = $intrimArray[$countyCode] + $data["count"];
}
}
// build the final desired array using interim array.
$finalArray = [];
foreach($intrimArray as $countyCode => $totalCount) {
array_push($finalArray, [
"county_code" => $countyCode,
"count" => $totalCount
]);
}
var_dump($finalArray);
As promised:
<?php
$initial_array = [
['country_code' => 54045, 'count' => 218],
['country_code' => 54045, 'count' => 115],
['country_code' => 54051, 'count' => 79],
];
$synth = [];
foreach ($initial_array as $sa) { # $sa: subarray
if (!isset($synth[$sa['country_code']])) {
$synth[$sa['country_code']] = 0;
}
$synth[$sa['country_code']] += $sa['count'];
}
print_r($synth); # Synthesis array: keys are country codes, values are cumulative counts.
# If you need the same format for both the initial and synthesis arrays, then continue with this:
$synth2 = [];
foreach ($synth as $k => $v) {
$synth2[] = ['country_code' => $k, 'count' => $v];
}
print_r($synth2);
?>
A fiddle for this code: https://3v4l.org/M8tkb
Best regards
I have two multidimensional arrays what I want to merge but, I want to skip the same values during merging. I tried several different ways what I find on the web, but nothing help me in my case.
My initial array is much bigger than this one, but here I just put an example:
$array1 = [
"aaa" => [
"aa1"=> [
"key1"=> "value1",
"key2"=> "value2",
],
"bbb"=> [
"bb1",
"bb2",
],
"ccc"=> [
"cc1",
],
],
"ooo" => [
"oo1"
]
];
And another one, which I want to merge in the first one:
$array2 = [
"aaa" => [
"bbb"=> [
"bb2",
],
"ccc"=> [
"cc2",
],
],
];
print_r of the array_merge_recurisive, using the method like:
print_r(array_merge_recursive($array1, $array2));
Array
(
[aaa] => Array
(
[aa1] => Array
(
[key1] => value1
[key2] => value2
)
[bbb] => Array
(
[0] => bb1
[1] => bb2
[2] => bb2
)
[ccc] => Array
(
[0] => cc1
[1] => cc2
)
)
[ooo] => Array
(
[0] => oo1
)
)
So, in the result as you can see array bbb have two bb2 values, but I need just one
The following function will remove duplicate values for an array recursively (edit: only for non-associative keys):
function array_unique_recursive(array $arr) {
if (array_keys($arr) === range(0, count($arr) - 1)) {
$arr = array_unique($arr, SORT_REGULAR);
}
foreach ($arr as $key => $item) {
if (is_array($item)) {
$arr[$key] = array_unique_recursive($item);
}
}
return $arr;
}
You can call it after array_merge_recursive.
Use array_replace_recursive instead of array_merge_recursive.
You can try this
array_unique(array_merge_recursive($array1,$array2), SORT_REGULAR);
Can someone help me with converting a php array in a grouped format? I am trying to group them by id. I would like to have the following array converted:
$Arr1=Array
(
0 => Array
(
"id" => "4123",
"test_number" => "1",
"sat_total" => "1050"
),
1 => Array
(
"id" => "4123",
"test_number" => "2",
"sat_total" => "1130"
),
2 => Array
(
"id" => "4123",
"test_number" => "3",
"sat_total" => "1120"
),
3 => Array
(
"id" => "5555",
"test_number" => "1",
"sat_total" => "1130"
),
4 => Array
(
"id" => "5555",
"test_number" => "2",
"sat_total" => "1160"
)
);
into this:
$Arr2=Array
(
0 => Array
(
"id" => "4123",
"Score1" => "1050",
"Score2" => "1130",
"Score3" => "1120"
),
1 => Array
(
"id" => "5555",
"Score1" => "1130",
"Score2" => "1160"
)
);
I have tried a little bit, but can't seem to find how to make it work.
You only need to iterate your rows of data, determine if each row is the first occurring id value or not, then either declare the initial values, or add a variably keyed element to the group. When the loop finishes, call array_values() to reindex the array (remove the temporary keys).
Code: (Demo)
$Arr1=[
["id" => "4123", "test_number" => "1", "sat_total" => "1050"],
["id" => "4123", "test_number" => "2", "sat_total" => "1130"],
["id" => "4123", "test_number" => "3", "sat_total" => "1120"],
["id" => "5555", "test_number" => "1", "sat_total" => "1130"],
["id" => "5555", "test_number" => "2", "sat_total" => "1160"]
];
foreach ($Arr1 as $set) {
if (!isset($result[$set['id']])) {
$result[$set['id']] = ['id' => $set['id'], 'Score1' => $set['sat_total']];
} else {
$result[$set['id']]['Score' . sizeof($result[$set['id']])] = $set['sat_total'];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'id' => '4123',
'Score1' => '1050',
'Score2' => '1130',
'Score3' => '1120',
),
1 =>
array (
'id' => '5555',
'Score1' => '1130',
'Score2' => '1160',
),
)
This method will find the scores matching the $id.
It uses three array_intersects to match all the values correct.
This method will only loop the number of unique IDs, in your case two times.
Plus the times to create the score keys.
I do agree with what ggorlen says about the keys. That will also create a more efficient code.
$ids = array_column($Arr1, "id");
$sat = array_column($Arr1, "sat_total");
foreach(array_unique($ids) as $id){
$new[$id] = ["id" => $id];
$tmp = array_values(array_intersect_key($sat,array_intersect_key($Arr1, array_intersect($ids, [$id]))));
for($i=1;$i<=count($tmp);$i++) $new[$id]["Score" . $i] = $tmp[$i-1];
}
var_dump($new);
https://3v4l.org/ag3To
The output is an associative array with id as key.
You can use array_values if you want to make it indexed.
Just to show how much more efficient the code can be with one score array.
This is what it would look like:
$ids = array_column($Arr1, "id");
$sat = array_column($Arr1, "sat_total");
foreach(array_unique($ids) as $id){
$new[] = ["id" => $id, "scores" => array_values(array_intersect_key($sat,array_intersect_key($Arr1, array_intersect($ids, [$id]))))];
}
var_dump($new);
https://3v4l.org/mdA0W
$arr2 = [];
$i = 0;
$length = count($arr1);
do {
$builder = $arr1[$i];
// grab the first item from the original array
$builder = [
// set its initial properties
'id' => $arr1[$i]['id'],
'Score1' => $arr1[$i]['sat_total'],
];
// initialise the subsequent score number
$testNumber = 2;
// prepare to look ahead in the original array for a matching id
while (($i + 1) < $length) { // only look ahead if it is possible to
if ($arr1[$i + 1]['id'] == $builder['id']) {
// did you find a matching id? if so, let's set the subsequent score
$builder["Score$testNumber"] = $arr1[$i + 1]['sat_total'];
$testNumber++; // increase the next score number
$i++; // increase the original array index
} else {
// no luck? let's go forwards and set the next record
break;
}
}
$arr2[] = $builder; // set the built record into the new array
$i++; // move the pointer forwards
} while ($i < $length); // as long as there are items ahead
Not often you get to use a do-while. But it works :)
Feed it your original array $arr1 and $arr2 will be set.
It works by looking forward for matching ids. This solution assumes your original array is ordered by id! So unless you trust the input - don't use this solution!
Otherwise this is a simple, fast, and fairly readable solution to what looks to me like a school exercise?
If you want something that is safe, the other solutions here are suitable.
I'm not sure this structure is ideal--it seems like your keys "Score1", "Score2" etc would be best as an array like scores => [1050, 1130, ...] and it feels like the ids should be keys in the result array. But in any case, this gives your requested output:
$res = [];
foreach ($arr as $e) {
if (!array_key_exists($e['id'], $res)) {
$res[$e['id']] = [];
}
$res[$e['id']]["Score".(count($res[$e['id']])+1)] = $e['sat_total'];
}
$count = 0;
foreach ($res as $k => $v) {
$res[$k]['id'] = $k;
$res[$count++] = $res[$k];
unset($res[$k]);
}
print_r($res);
Output
Array
(
[0] => Array
(
[Score1] => 1050
[Score2] => 1130
[Score3] => 1120
[id] => 4123
)
[1] => Array
(
[Score1] => 1130
[Score2] => 1160
[id] => 5555
)
)
Note that I did two passes which is a little verbose, but taking the time to key in the data ids into the array in the first pass should improve a linear search through the array for each element into O(1) hashing, so I think it's worth the extra loop block.
I have an array with information that I get from the Amazon API and parsed it using SimpleXML. This gives me an array that looks like this :
[
[
0 => SimpleXMLElement Object (0 => B00TU53O8Q)
], [
0 => SimpleXMLElement Object (0 => B00TU53O8Q),
1 => SimpleXMLElement Object (0 => B015K13HWQ)
], [
0 => SimpleXMLElement Object (0 => B00TU53O8Q)
], [
...
]
]
Now, I want to convert this array to a more simplified format that no longer has any SimpleXML objects in them anymore.
Basically, I just want an array with only the strings they represent :
[
0 => B00TU53O8Q,
1 => B015K13HWQ,
2 => B00TU53O8Q,
1 => B00TU53O8Q
...
]
I then want to split that array into a 2-dimentional array, that looks something like this :
[
0 => [
0 => B00TU53O8Q
1 => B00TU53O8Q
2 => B015K13HWQ
3 => B00TU53O8Q
4 => B00TU53O8Q
],
1 => [
0 => B015K13HWQ
...
]
...
]
I don't know how to do this. Can you please help me?!
Here is a function to process your input:
function translate($data, &$result) {
if (is_array($data)) {
foreach($data as $element) {
translate($element, $result);
}
} else {
$result[] = (string) $data;
}
}
Call it like this:
// some test data:
$data = array(
array(
new SimpleXMLElement("<test>B00TU53O8Q</test>")
),
array(
new SimpleXMLElement("<test>B00TU53O8Q</test>"),
new SimpleXMLElement("<test>B015K13HWQ</test>")
),
array(
new SimpleXMLElement("<test>B00TU53O8Q</test>")
),
array(
new SimpleXMLElement("<test>B00TU53O8Q</test>"),
new SimpleXMLElement("<test>B015K13HWQ</test>")
)
);
$result = array();
translate($data, $result);
If you want to break up the $result array in chunks of 5, then proceed like this:
$chunks = array();
while (count($result)) {
$chuncks[] = array_slice($result, 0, 5);
$result = array_slice($result, 5);
}
print_r ($chuncks);
Ouput, based on test data, gives 2 chunks:
Array
(
[0] => Array
(
[0] => B00TU53O8Q
[1] => B00TU53O8Q
[2] => B015K13HWQ
[3] => B00TU53O8Q
[4] => B00TU53O8Q
)
[1] => Array
(
[0] => B015K13HWQ
)
)
right off the bat I think your if statement is wrong. Should be a double == if you are making a comparison. Essentially you are setting $asinValue equal to 'Asin Not Found' and it will evaluate true. It does not seem like you will ever get to the else portion of your code.