Right way to separate array specific values into another arrays - php

There is the following array in my application:
array (
[item_name_1] => GTA V
[item_quantity_1] => 4
[item_price_1] => 5990
[item_name_2] => Watch_Dogs
[item_quantity_2] => 1
[item_price_2] => 5990
)
I want to divide/split this array into two pieces like that:
array (
[item_name_1] => GTA V
[item_quantity_1] => 4
[item_price_1] => 5990
)
array (
[item_name_2] => Watch_Dogs
[item_quantity_2] => 1
[item_price_2] => 5990
)
If you didn't realized, I want to separate items suffixed by 1 and 2 – and successively – unto different matrices and I really don't see the best way to perform this. Maybe regex?
I already tried to play with explode() and implode(), but no success – I have no creativity enough to explore their best.

<?php
$src = array (
'item_name_1' => 'GTA V',
'item_quantity_1' => 4,
'item_price_1' => 5990,
'item_name_2' => 'Watch_Dogs',
'item_quantity_2' => 1,
'item_price_2' => 5990,
);
$dest = array();
foreach($src as $k => $v) {
$sfx = preg_replace('/.*?_([0-9]+)$/', '$1',$k);
$dest[$sfx][$k] = $v;
}
print_r($dest);

Related

Searching 4 level deep array in PHP

Good evening,
I found myself in a bit of a pickle here, with an overcomplicated (i think) $_SESSION array that is set right after a user logs in and contains the info of all User Groups where that user is on, and also this user type of permissions on Group of Devices where that specific user group is allowed.
Here's the deal with irrelevant info ommited:
Array
(
... other stuff ...
[user_groups] => Array
(
[0] => Array
(
[GroupUsersId] => 4
[GroupUsersName] => XXXX
[idUserType] => 2
[NameTypeUser] => Manager
[DevicesAllowed] => Array
(
[GroupDevicesId] => Array
(
[0] => 2
)
[DevicesOnGroup] => Array
(
[0] => 22,24,16
)
)
)
[1] => Array
(
[GroupUsersId] => 5
[GroupUsersName] => YYYY
[idUserType] => 3
[NameTypeUser] => Guest
[DevicesAllowed] => Array
(
)
)
[2] => Array
(
[GroupUsersId] => 1
[GroupUsersName] => ZZZ
[idUserType] => 1
[NameTypeUser] => Admin
[DevicesAllowed] => Array
(
[GroupDevicesId] => Array
(
[0] => 2
)
[DevicesOnGroup] => Array
(
[0] => 1,5,13,12,17,21,22,24,16
)
)
)
)
... more stuff ...
I need to find out what kind of permissions, if any, does the guy has if trying to browse the device with, let's say, DeviceId = 5. If that particular Id is not on any of the arrays, the user isn't even allowed to see it...
I already tryed to change the code in this question How to search by key=>value in a multidimensional array in PHP, but I guess I'm missing some kind of iteration over the arrays.
Any help?
Cheers and thanks in advance.
Edit: $_SESSION can be changed if needed...
(Updated as per comment below) I might be completely missing your point, but would not just iterative processing of your array help?
$user_groups = array(
0 => array(
'GroupUsersName' => 'XXX',
'NameTypeUser' => 'Admin',
'idUserType' => 3,
'DevicesAllowed' => array(
'DevicesOnGroup' => array(
1, 2, 3
)
)
),
1 => array(
'GroupUsersName' => 'YYY',
'NameTypeUser' => 'ReadOnly',
'idUserType' => 1,
'DevicesAllowed' => array(
'DevicesOnGroup' => array(
3, 4, 5
)
)
)
);
$device = 3;
$right = 0;
foreach ($user_groups as $group) {
if (array_key_exists('DevicesOnGroup', $group['DevicesAllowed'])) {
if (in_array($device, $group['DevicesAllowed']['DevicesOnGroup'])) {
if ($group['idUserType'] > $right) {
$right = $group['idUserType'];
}
}
}
}
print_r($right);
Outputs:
3
If you would ask for device which is in no group, it would return 0 (i.e. no access).
iterate the array like this
$guysDeviceId ;
$bGuyMayPass = false;
foreach($_SESSION["user_group"] as $userGroup ){
if(!isset($userGroup[DevicesAllowed]) || !isset($userGroup[DevicesAllowed][DevicesOnGroup])){
continue;
}
if(in_array($userGroup[DevicesAllowed][DevicesOnGroup], $guysDeviceId ){
$bGuyMayPass= true;
}
}
if($bGuyMayPass){
//login, whatever
}

Group rows on two column values and sum the values of specific key [duplicate]

This question already has answers here:
Group multidimensional array data based on two column values and sum values of one column in each group
(5 answers)
Closed 5 months ago.
I have following array where I am trying to merge the elements which has shelf and weight value as duplicate and sum the value of piece key.
Array
(
[0] => Array
(
[shelf] => Left
[weight] => 10.000
[piece] => 1
)
[1] => Array
(
[shelf] => Right
[weight] => 04.000
[piece] => 12
)
[2] => Array
(
[shelf] => Right
[weight] => 04.000
[piece] => 4
)
[3] => Array
(
[shelf] => Right
[weight] => 07.000
[piece] => 8
)
)
Currently I am getting following desired output with help of following SQL statement by creating the temporary table with following fields shelf, weight and piece and inserting all the four values and parsing the result in PHP with following select query
SELECT shelf, weight, SUM(piece) FROM temp GROUP BY CONCAT(shelf, weight)
Array
(
[0] => Array
(
[shelf] => Left
[weight] => 10.000
[piece] => 1
)
[1] => Array
(
[shelf] => Right
[weight] => 04.000
[piece] => 16
)
[3] => Array
(
[shelf] => Right
[weight] => 07.000
[piece] => 8
)
)
However I am believe that this can be simply achieved by PHP, but can't get my head around. Can somebody please point what I might be missing ?
Note to Moderators and SO Vigilante
Please don't take it personal but before marking or even saying this is duplicate, read my question thoroughly and understand what I am trying to achieve and only then if you agree kindly explain in detail why do you think its duplicate, rather than simply arguing on base of question with similar title
I have gone through these questions, but they don't work in my scenario, as they try to merge array and sum value based on one specific element which is usually either ID, but in my case its uniqueness is judged on combination of elements (not one)
1, 2, 3
If you absolutely have to do this in PHP, then something like:
$data = array(
array(
'shelf' => 'Left',
'weight' => '10.000',
'piece' => 1,
),
array(
'shelf' => 'Right',
'weight' => '04.000',
'piece' => 12,
),
array(
'shelf' => 'Right',
'weight' => '04.000',
'piece' => 4,
),
array(
'shelf' => 'Right',
'weight' => '07.000',
'piece' => 8,
),
);
$newData = array();
$result = array_reduce(
$data,
function($newData, $value) {
$key = $value['shelf'].$value['weight'];
if (!isset($newData[$key])) {
$newData[$key] = $value;
} else {
$newData[$key]['piece'] += $value['piece'];
}
return $newData;
},
$newData
);
var_dump($result);
will work, but I really do believe that you're creating major performance problems for yourself with your whole approach to this problem

Iterating through multiple arrays and assigning positions

Been working on this for 4 hours. My eyes are starting to hurt and my brain is weary from paradox.
So here is the setup. 3 arrays:
An array of posts that are advertisements
An array of normal posts
An array of taken positions which is pulled from array 1
The ad array has predefined spots.
I have merged the 2 arrays because the ads are basically integrated into the normal flow of posts. I have even been able to assign every post a spot based on the natural order of the posts, and the assigned spot for the ad. So if a post's natural spot has an ad in it, then that posts's position needs to bump forward one. This is easy if there is only 1 ad in the stream. But the thing is set up for multiple ads of arbitrary number.
So here is how I bump the position of each non-ad element in the array. I could run this again a few times I think and that should cover when there are additional ads but it seems wrong and unholy.
Wondering if anyone can solve this problem because I am sick of the taste of my own tears.
if(in_array($newarray[$key]['position'],$taken)){
$newkey = ($newarray[$key]['position'] + 1);
$newarray[$key]['position'] = $newkey;
$taken[] = $newkey;
In the end I need the merged array with all positions correctly assigned and unique.
You could write a recursive function to pull the next available position number, but if you're working with a small number of posts + ads, something like below would be quick and easy. Note that this assumes you need to preserve the original keys for the ads and posts arrays. If you don't need to do that then you can simplify it even further.
// Sample array of ads
$ads = array('ad1' => array('position' => 1),
'ad2' => array('position' => 4),
'ad3' => array('position' => 6),
'ad4' => array('position' => 10));
// Identify ad positions
foreach ( $ads as $k => $v ) {
$adPositions[$v['position']] = $v['position'];
}
// Identify available positions
$availablePositions = array_combine(range(1,100), range(1,100));
$availablePositions = array_diff_key($availablePositions, $adPositions);
// Sample posts
$posts = array('post1' => array('position' => false),
'post2' => array('position' => false),
'post3' => array('position' => false),
'post4' => array('position' => false),
'post5' => array('position' => false),
'post6' => array('position' => false));
// Use first (lowest number) available position as post position
foreach ( $posts as $k => $v ) {
$posts[$k]['position'] = array_shift($availablePositions);
}
// Merge arrays
$merged = array_merge($ads, $posts);
// Create list of positions for use with array_multisort
foreach ( $merged as $k => $v ) {
$position[$k] = $v['position'];
}
// Sort $merged by ['position']
array_multisort($position, SORT_ASC, $merged);
Gives you:
Array
(
[ad1] => Array
(
[position] => 1
)
[post1] => Array
(
[position] => 2
)
[post2] => Array
(
[position] => 3
)
[ad2] => Array
(
[position] => 4
)
[post3] => Array
(
[position] => 5
)
[ad3] => Array
(
[position] => 6
)
[post4] => Array
(
[position] => 7
)
[post5] => Array
(
[position] => 8
)
[post6] => Array
(
[position] => 9
)
[ad4] => Array
(
[position] => 10
)
)

Reducing multidimensional array

I have the following multidimensional array:
Array
(
[0] => Array
(
[area] => 5
[estante] => 5
[anaquel] => 5
[no_caja] => 5
[id_tipo] => 3
[nombre_tipo] => Administrativo
)
[1] => Array
(
[area] => 5
[estante] => 5
[anaquel] => 5
[no_caja] => 5
[id_tipo] => 1
[nombre_tipo] => Copiador
)
[2] => Array
(
[area] => 5
[estante] => 5
[anaquel] => 5
[no_caja] => 5
[id_tipo] => 2
[nombre_tipo] => Judicial
)
)
and I want to reduce it by having all the different values (intersection) between them. The dimension of the array may change (I'm retrieving the info from a database). I have thought in using functions like array_reduce and array_intersect, but I have the problem that they work only with one-dimension arrays and I can't find the way to pass an indefinite (not previous known) number of parameters to these function. I'd like to have an output like this:
Array([0]=>Copiador, [1]=>Administrativo, [2]=>Judicial).
How can I do this?
Thanks in advance.
$arr=array(
array (
'area' => 5 ,
'estante' => 5 ,
'anaquel' => 5,
'no_caja' => 5,
'id_tipo' => 3,
'nombre_tipo' => 'Administrativo'),
array (//etc.
)
);
$fn=function(array $a, $k){
if(array_key_exists($k,$a)) return $a[$k];
};
$b=array_map($fn,$arr,array_fill(0,count($arr),'nombre_tipo'));
print_r($b);
/*
Array
(
[0] => Administrativo
[1] => Copiador
[2] => Judicial
)
*/
$reduced = array();
foreach ($oldarray as $value) {
$reduced[] = $value['nombre_tipo'];
}
Although, a better solution may be to just modify your SQL query so you get the correct data to begin with.
Note: you can also do it with array_reduce, but I personally prefer the method above.
$reduced = array_reduce($oldarray,
function($a, $b) { $a[] = $b['nombre_tipo']; return $a; },
array()
);
This task is exactly what array_column() is for -- extracting columnar data.
Call this:
var_export(array_column($your_array, 'nombre_tipo'));
This will output your desired three-element array. ...I don't understand the sorting in your desired output.
Seems like you want array_map
$newArr = array_map(function($a) {
return $a['nombre_tipo'];
}, $oldArr);
var_dump($newArr);

Creating arrays dynamically using PHP

Hey folks, please lend a hand to a PHP beginner. I'm trying to put a load of dynamically created variabled into an array to re-read later, reason is a SOAP message sent is a mess and im trying to create a less complicated array:
$placea = "place a";
$placeb = "place b";
$myarray = array();
echo "<pre>";
print_r($myarray);
echo "</pre>";
what i want to be able to do:
Array
(
[0] => [Place A] => Array
(
[0] => [Accommodation] => Array
(
[RoomId] => 001
[RoomAvail] => true
[Date] => 12.04.2011
)
[1] => [Accommodation] => Array
(
[RoomId] => 002
[RoomAvail] => true
[Date] => 12.04.2011
)
) Array
(
[1] => [Place B] => Array
(
[0] => [Accommodation] => Array
(
[RoomId] => 101
[RoomAvail] => true
[Date] => 12.04.2011
)
[1] => [Accommodation] => Array
(
[RoomId] => 102
[RoomAvail] => true
[Date] => 12.04.2011
)
)
)
how would i write that out in php? sorry if its bleek and/or the array structure is incorrect
So you just need to use the array initializer repetitively.
If you want to initialize an array in PHP with some values, say 1 through 4, you make a call like:
$foo = array(1, 2, 3, 4);
And if you want to make an associative array, where you store some key/value pairs, you make a call like:
$foo = array('key' => 'value', 'other key' => 'other value');
But you can of course nest calls, and mix and match layers of associative and non associative arrays to achieve something like your example, e.g.:
$foo = array(
'Place A' => array(
// note use of first array on the next line is
// to generate structure like [0] => 'Accomodation' => ...
array('Accomodation' => array(
'RoomId' => '001',
'RoomAvail' => true,
'Date' => '12.04.2011')
)),
array('Accomodation' => array(
'RoomId' => '002',
'RoomAvail' => true,
'Date' => '12.04.2011')
))
),
'Place B' => array(
array('Accomodation' => array(
'RoomId' => '101',
'RoomAvail' => true,
'Date' => '12.04.2011')
)),
array('Accomodation' => array(
'RoomId' => '102',
'RoomAvail' => true,
'Date' => '12.04.2011')
))
)
);
This will very nearly produce what you're looking for, to make it replicate exactly what you have you would wrap each 'Place A' with an array and each "place" would get its own assignment to some variable $foo (I assumed this wasn't actually what you wanted and wrote something maybe slightly more intuitive).
If you want to have a 'less complicated' array, you have a two arrays, one fore place a and one for place b and then merge them using array_merger() http://www.php.net/manual/en/function.array-merge.php.
Study up on the array functions control structures in the manual. Many different ways of achieving bloated arrays uglying up your code.
This would dynamically create an array.
foreach($soapResponse as $key1 => $value1){
foreach($value as $key2 => $value2){
// $key1 = Place A or B
// value1 = array of values
$arrayResponse[$key1][$key2] = $value2;
}
}

Categories