Handling multi-dimensional PHP Array - php

I have arrays of fonts with their name and weight e.g.
print_r($fontarray1);
Array (
[font] => Open+Sans
[weight] => normal
)
print_r($fontarray2);
Array (
[font] => Open+Sans
[weight] => bold
)
print_r($fontarray3);
Array (
[font] => Lato
[weight] => bolditalic
)
I have many arrays of fonts $fontarray1, $fontarray2, $fontarray3.. I want to make one final array of fonts and their weights.. for example, if "Open+Sans" is already in the final array, it should not be added, but if "Open+Sans" is in final Array with a different "weight" then only the "weight" should be added alongwith the "Open+Sans" key.. the expected result should be something like:
Array (
[font] => Oen+Sans
[weight] => Array (
[0] => normal
[1] =>bold
)
[font] => Lato
[weight] => Array (
[0] => bolditalic
)
)
I tried something like below, but confused on how to add another array within one array..:
$final_arr = Array();
if (!in_array($fontarray1['font'], $final_arr)) {
$final_arr []= $fontarray1['font'];
} else {
// already in array, lets check font weight
}
}
any help or thought would be highly appreciated. cheers

First
Use array_merge
<?php
$beginning = 'foo';
$end = array(1 => 'bar');
$result = array_merge((array)$beginning, (array)$end);
print_r($result);
?>
Second
Use array_unique
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>

Look` like structure like this can be usefull for you:
Array(
"fontName" => Array(
[weight] => Array(
[0] => "normal"
)
)
)
And your function would be like
$final_arr = Array();
$fontName = $fontarray1['font'];
$fontWeight = $fontarray1['weight'];
if (!isset($final_arr[$fontName])) {
$final_arr[$fontName] = array('weight' => $fontWeight);
} else {
$final_arr[$fontName]['weight'][] = $fontWeight;
}

You're just trying to add $fontarray1 to $final_arr?
$final_arr[] = $fontarray1
Creating a multidimensional array:
$theArray = array();
$theArray[] = array('key1'=>'val1', 'key2'=>'val2'); // creates a subarray

Related

Remove subsets from each row where the same subset is found in another row

I need to remove objects from a 3d array where the same two-property object is found in any other row.
I previously asked this similar question, but my new requirements are slightly different because I was keeping one of the encountered duplicates. Now I would like for both/all encountered duplicates to be removed.
[
[
["name" => "John", "surname" => "Smith"],
["name" => "Kate", "surname" => "Winston"]
],
[
["name" => "Kate", "surname" => "Winston"],
["name" => "Jack", "surname" => "Irving"]
],
]
Desired filtered result with same original structure:
[
[
["name" => "John", "surname" => "Smith"],
],
[
["name" => "Jack", "surname" => "Irving"]
],
]
Seems like others answers don't see their own final results and don't read desired output.
Here a little bit hard solution but it works well.
Note: the input data array must have 2 object indexes and 2 arrays of objects for comparing, otherwise, it should be fixed.
$ar = Array (
0 => [(object)["name"=>"John", "surname"=>"Smith"], (object)["name"=>"Kate", "surname"=>"Winston"]],
1 => [(object)["name"=>"Kate", "surname"=>"Winston"], (object)["name"=>"Jack", "surname"=>"Irving"]]
);
$arr = [];
$k = 0; // do `if statement` only once
foreach($ar as $num=>&$subar){
foreach($subar as $num2=>$pers){
$subar[$num2] = (array)$pers; // object to array
if (!$k) {
$keys = array_keys($subar[$num2]); // collect "name" and "surname" in an array
$k++;
}
foreach($subar[$num2] as $a=>$b){
$seq = array_search($a,$keys); // index of the current key
if (!$seq) { // 0 -> "name", 1 -> "surname"
$arr[$num][$b] = '';
} else {
$arr[$num][$subar[$num2][current($keys)]] = $b;
}
}
}
}
$diff[] = array_diff($arr[0],$arr[1]); // clear duplicates from 1-st set
$diff[] = array_diff($arr[1],$arr[0]); // clear duplicates from 2-nd set
Gives result:
Array
(
[0] => Array
(
[John] => Smith
)
[1] => Array
(
[Jack] => Irving
)
)
And after you can re-create the output array:
// creating a new array
$res = [];
foreach($diff as $num=>$ns){
foreach($ns as $name=>$surname){
foreach($keys as $ind=>$key){
if ($ind % 2 == 0){
$tmp[$key] = $name; // put name
} else {
$tmp[$key] = $surname; // put surname
}
}
$res[$num] = (object)$tmp; // array to object
}
}
Output will be:
Array
(
[0] => stdClass Object
(
[name] => John
[surname] => Smith
)
[1] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
Demo
In case of string values in the input arrays, i.e.:
$ar = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
You need a little fix:
...
foreach($ar as $num=>&$subar){
$ar[$num] = json_decode($subar);
foreach($subar as $num2=>$pers){
...
The same output you will get.
Demo
It's easier if you don't trim away the brackets [], as you stated that you did in the comments. That way, they are proper JSON strings, which we can use in PHP.
Map (or loop) over your array, and build up a $result array, where you append all the arrays from your decoded JSON. Once you have your final $result, you have an array that looks somewhat like
Array (
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[2] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
We have all the values in an actual array now, but there are duplicates -- which can be removed using array_unique() with the SORT_REGULAR flag.
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$result = [];
array_map(function($v) use (&$result) {
$result = array_merge($result, json_decode($v, true));
}, $array);
print_r(array_unique($result, SORT_REGULAR));
Final output:
Array
(
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
Live demo at https://3v4l.org/q6pZc
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$resultArray = [];
foreach ($array as $item) {
$bufferArray = array_merge($resultArray, json_decode($item));
foreach ($bufferArray as $elements) {
$key = $elements->name . $elements->surname;
if (array_key_exists($key, $resultArray)) {
unset($resultArray[$key]);
} else {
$resultArray[$key] = $elements;
}
}
}
print_r($resultArray);
Output
Array
(
[KateWinston] => stdClass Object
(
[name] => Kate
[surname] => Winston
)
[JackIrving] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
can rewrite this into more serious code )
To remove objects from each row where a given object exists any where in any other row, you can make iterates calls of array_udiff(). Inside the function, the first parameter should be the currently iterated row and the next/subsequent parameter(s) should all of the other rows in the entire array. The last parameter is the callback which compares whole objects to whole objects via PHP's performance-optimized algorithm.
My snippet below will not only handle your 2-row array, it will also handle arrays with 3 or more rows.
Code: (Demo)
$result = [];
foreach ($array as $i => $objs) {
$cache = $array[$i];
unset($array[$i]);
$params = [
$objs,
...$array,
fn($a, $b) => $a <=> $b
];
$result[] = array_udiff(...$params);
$array[$i] = $cache;
}
var_export($result);
To be clear, this snippet will work the same if the array of arrays of objects is an array of arrays of arrays.

php array find duplicates, sum them up & delete duplicates

i have an array:
Array
(
[0] => Array
(
[setid] => 2
[income] => 100
)
[1] => Array
(
[setid] => 2
[income] => 120
)
[2] => Array
(
[setid] => 3
[income] => 700
)
)
i need to find entrys with the same setid, sum their income up and delete duplicate entrys - in the end it should look like this:
Array
(
[0] => Array
(
[setid] => 2
[income] => 220
)
[1] => Array
(
[setid] => 3
[income] => 700
)
)
does someone know a sophosticated solution for my problem or do i have to take the long road and do every step manually?
thanks and greetings
Just create a new array which you make fast adressable by using the setid as key. And reindex the array at the end.
$result = array();
foreach ($array as $val) {
if (!isset($result[$val['setid']]))
$result[$val['setid']] = $val;
else
$result[$val['setid']]['income'] += $val['income'];
}
$result = array_values($result); // reindex array
This should work:
$values = array();
foreach($array as $val) {
if(isset($values[$val['setid']])) {
$values[$val['setid']] += $val['income'];
} else {
$values[$val['setid']] = $val['income'];
}
}
//all values are now in $values array, keys are setid and values are income
Write your own function, that's no long road at all.
$result = array_reduce($originalArray, function($memo, $item){
isset($memo[$item['setid']])
? $memo[$item['setid']] = $item['income']
: $memo[$item['setid']] += $item['income'];
return $memo;
}, []);
You should use the array_unique function that php's official site offers.
An example:
<?php
$input = array("a" => "green", "red", "b" => "green", "blue", "red");
$result = array_unique($input);
print_r($result);
?>
Output:
Array
(
[a] => green
[0] => red
[1] => blue
)
To sum the duplicated values you can use the array_count_values function:
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Output would be:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

php building / populating an Array of Arrays

I have seen alot of tutorial on how to get the data out of a 2D array but I need to build one similar to this and I have not found any logic I can follow:
$array = array("socks" => array("blue", "red", "green"),
"shirts" => array("small", "medium", "large"));
I cant seem to figure out the logic to even start the code....
for each clothingType // I did this
get options // I did this
for each option //I did this
add to the clothingOption Array //... help!
Im only stuck on the building of the clothingOption 2D Array
could it be someting like
foreach clothingType as $kClothes =>VClothes
get Options
for each Options as $kOptions =>$VOption
$array[$VClothes][]= $VOption
Thanks and I hope this is not too vague....
How about the following?
<?php
function getMe($type) {
//do some processing and construct array
return array('a','b','c');
}
$myTypes = array('type1','type2','type3');
$answer = array();
foreach($myTypes as $val) {
$answer[$val] = getMe($val);
}
print_r($answer);
?>
Output:
Array ( [type1] => Array ( [0] => a [1] => b [2] => c ) [type2] => Array ( [0] => a [1] => b [2] => c ) [type3] => Array ( [0] => a [1] => b [2] => c ) )
maybe (sorry for errors - by hand):
//$array = array("socks" => array("blue", "red", "green"),
// "shirts" => array("small", "medium", "large"));
$types = array('socks', 'shirts');
$socks = array("blue", "red", "green");
$shirts = array("small", "medium", "large");
$array = array();
foreach ($types as $type) {
foreach($$type as $cloth) {
$array[$type][] = $cloth;
}
}
print_r($array);

Merging multiple PHP arrays

My problem is this: I'm creating an Array in order to store these 2 types of 'refinement'. However, what is happening is as the information is collected from the database, each 'refinement' is assigned to it's own specific entry when the arrays are created within the while loop.
while($row = mysqli_fetch_array($result2, MYSQLI_ASSOC)){
etc...
}
So for instance, the 1st array would be a reference to 'Die Hard' and the 2nd, 'Breaking Bad' and the 3rd, 'Greys Anatomy'. What i'm trying to achieve is to merge them into 1 single array.
Array
(
[genreType] => Action
[mediaType] => Film
)
Array
(
[genreType] => Action
[mediaType] => TV
)
Array
(
[genreType] => Drama
[mediaType] => TV
)
Thanks for any help.
Try looking at this, http://php.net/manual/en/function.array-merge.php
<?php
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>
OUTPUT
Array (
[color] => green
[0] => 2
[1] => 4
[2] => a
[3] => b
[shape] => trapezoid
[4] => 4
)
Why can't you just use array_merge? from the php docs http://php.net/manual/en/function.array-merge.php
while{$row...
{
$movies[] = $row;
//OR
$tmp['genreType'] = $row['genre'];
//and the like.....
$movies[] = $tmp;
}
Resulting in
$movies = array(
array(
"title"=>"Die Hard",
"genreType"=>"Action",
"mediaType"=>"Film"
),
array(
"title"=>"some other movie",
"genreType"=>"Comedy",
"mediaType"=>"TV"
)
);
like this?

How can I group arrays into one array in php?

I would like to convert / form the following arrays as example:
Array ( [product_category] => for-women ) Array ( [brand] => 7-diamonds ) Array ( [size] => 12 ) Array ( [color] => 882536 )
Into one array that just merges each array pair and put them altogether :
Array ( [product_category] => for-women [brand] => 7-diamonds [size] => 12 [color] => 882536 )
I tried array_merge and it didn't work. The array out put in my code is from $_SESSION which returns an array (a pair key=> value) like this:
foreach($_SESSION as $k => $v) {
if (strstr($k, 'saved_query_') == true) {
$saved = array_merge($v);
}
}
So I get each array by looping through session which has a query, the result is array pair, I want to combine all pairs found (Do not know how to use array_merge in that case).
I tried array_combine and array_merge they do not seem like the functions I need based on php manual:
array_combine — Creates an array by using one array for keys and another for its values
Which I do not want to do, I just want to copy/move small arrays in one array, without changing any pairing/key/value.
You can try using array_merge
$array0 = Array ( "product_category" => "for-women" );
$array1 = Array ( "brand" => "7-diamonds" ) ;
$array2 = Array ( "size" => "12" ) ;
$array3 = Array ( "color" => "882536" );
$array = array_merge($array0,$array1,$array2,$array3);
print_r($array);
Output
Array ( [product_category] => for-women [brand] => 7-diamonds [size] => 12 [color] => 882536 )
See Demo
* ----- Update ----- *
If you are looking through a session
$_SESSION = Array();
$_SESSION[0] = Array("product_category" => "for-women");
$_SESSION[1] = Array("brand" => "7-diamonds");
$_SESSION[2] = Array("size" => "12");
$_SESSION[3] = Array("color" => "882536");
$final = array();
foreach ( $_SESSION as $key => $value ) {
$final = array_merge($final, $value);
}
print_r($final);
Use array_merge_recursive() :
$result = array_merge_recursive($ar1, $ar2 [, array $...]);
Example: http://codepad.viper-7.com/Yr0LTb
Use array_merge instead.
$ret = array_merge($arr1, $arr2, $arr3);
With your code, you should do:
$saved = array_merge($saved, $v);
You should have a look at the array_merge() function in PHP: http://php.net/manual/en/function.array-merge.php
Simply use as follows:
$array1 = Array ( [product_category] => for-women );
$array2 = Array ( [brand] => 7-diamonds );
$array3 = Array ( [size] => 12 );
$array4 = Array ( [color] => 882536 );
$combined = array_merge($array1, $array2, $array3, $array4);

Categories