PHP three dimensional array, reset key if second element different - php

Let say i have this print_r output, this is dynamic and not same each condition
Array
(
[2] => Array
(
[1] => 24
[2] => 23,25
)
[3] => Array
(
[3] => 27
[4] => 27,26
[5] => 28,27,26
)
)
As you can see, array element [3] starts from [3][4][5], how do it make it start from [1][2]...[n] if the 2nd element is not same.
Ideally what i am looking for is something like
Array
(
[2] => Array
(
[1] => 24
[2] => 23,25
)
[3] => Array
(
[1] => 27
[2] => 27,26
[3] => 28,27,26
)
)
How do i achieve that? Thanks

array_values returns the values of an array with new numeric indices:
foreach($a as $k => $v) {
$a[$k] = array_values($v);
}
Add conditions if you only want to re-index some of your sub-arrays.
Functional approach:
$a = array_map(function($v) {
return array_values($v);
}, $a);

Related

Sort a subArray by based on order of Array in php?

I have a big array as $orderArr:
$orderArr = array("IZQ", "AOH", "VNP", "ICW", "IOQ", "BXP", "SHH", "EAY", "ZAF", "CUW");
which looks like
Array ( [0] => IZQ [1] => AOH [2] => VNP [3] => ICW [4] => IOQ [5] => BXP [6] => SHH [7] => EAY [8] => ZAF [9] => CUW )
and I have two small arrays as $subArr1 and $subArr2:
$subArr1 = array("VNP", "BXP", "ICW", "IZQ");
$subArr2 = array("ZAF", "IZQ", "AOH");
looks like
Array ( [0] => VNP [1] => BXP [2] => ICW [3] => IZQ )
Array ( [0] => ZAF [1] => IZQ [2] => AOH )
Both small arrays (sub array) own elements belong to the big array.
I want to sort two small arrays according to the order of big array, as following:
Array ( [0] => IZQ [1] => VNP [2] => ICW [3] => BXP )
Array ( [0] => IZQ [1] => AOH [2] => ZAF )
I am looking for the simplest codes to do it in php. Any suggestions are welcome.
Probably the simplest would be to compute the intersection and it will return in the order of the first array:
$subArr1 = array_intersect($orderArr, $subArr1);
That will return with the keys of the first array; if you want to reindex instead:
$subArr1 = array_values(array_intersect($orderArr, $subArr1));
You could use usort to sort based on array position:
usort($subArr1, function ($a, $b) use ($orderArr) {
return (array_search($a, $orderArr) < array_search($b, $orderArr)) ? -1 : 1;
});
var_dump($subArr1);

Rearrange an array by an array of indexes - PHP

I have an array of $Percentages1 that I have ordered in descending order using arsort() and then I have taken an array containing the new key order using array_keys() called $keyorder
My question is how do I now rearrange another array $Percentages2 into the same key order as $Percentages1?
Any help will be greatly appreciated, thanks very much!
Edit - Code as requested:
//$Percentages1 before sort for example =
// Array ( [0] => 5.10 [1] => 1.52 [2] => 8.42 [3] => 1.11 [4] => 1.35 )
arsort($Percentages1);
//$Percentages1 after sort =
// Array ( [2] => 8.42 [0] => 5.10 [1] => 1.52 [4] => 1.35 [3] => 1.11 )
$keyorder = array();
//So $keyorder is =
// Array ( [0] => 2 [1] => 0 [2] => 1 [3] => 4 [4] => 3 )
$keyorder = array_keys($Percentages1);
//Now I want to do something here to rearrange a $Percentages2 array
//in the same index order as $keyorder.
//For example from this
// Array ( [0] => 2.50 [1] => 3.52 [2] => 9.42 [3] => 9.81 [4] => 0.35 )
//To...
// Array ( [2] => 9.42 [0] => 2.50 [1] => 3.52 [4] => 0.35 [3] => 9.81 )
If you are not adverse to creating another array variable, the simplest course here is just to loop over $keyorder and append the elements at the corresponding key from $Percentages2 onto a new array;.
// Sorted as you already have it...
$keyorder = array_keys($Percentages1);
// Final array
$output = array();
foreach ($keyorder as $key) {
$output[$key] = $Percentages2[$key];
}
// Don't need the source anymore
unset($Percentages2);
Their key order as appended onto $output will be retained in the final result.
Given your input arrays, this produces
print_r($output);
Array
(
[2] => 9.42
[0] => 2.5
[1] => 3.52
[4] => 0.35
[3] => 9.81
)
You actually don't need to use array_keys(). Following the call to arsort(), you can foreach over the sorted $Percentages1 and sort to $output by key:
// Skip array_keys, and read the sorted array directly
arsort($Percentages1);
foreach ($Percentages1 as $key => $value) {
// Same as before inside the loop
$output[$key] = $Percentages2[$key];
}

Sort Multi Dimensional Array by its keys from another arrays values

This is an issue I haven't come across before, and there doesn't appear to be a function for this.
I'm trying to sort the following multi dimensional array by its keys
Array (
[hiphop] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[rnb] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[dubstep] => Array ( )
[reggae] => Array ( )
[trap] => Array ( )
)
From this arrays values
Array (
[0] => hiphop
[1] => dubstep
[2] => reggae
[3] => trap
[4] => rnb
[5] => rnb
)
Has anyone attempted this before or know a workaround?
An explanation would be great as I'm new to multi dimensional arrays
Many thanks in advance if you can help!
The final output would match the value organsiation from the non multi dimensional array like so
Array (
[hiphop] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[dubstep] => Array ( )
[reggae] => Array ( )
[trap] => Array ( )
[rnb] => Array (
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
)
The easiest Way would be to "flip" the array definining the sorting - then grab the values matching the new keys in the other array:
$s = array ("hiphop","dubstep","reggae","trap","rnb");
$target = array_flip($s);
foreach($target AS $key => &$value){
$value = $array_containing_unsorted_values[$key];
}
Note: does not work if the same value appears twice in the sorting array - but that never should happen, cause does not make sence for a sorting-definition.
Should be way faster than using array_search 2 times within each sorting comparission.
result:
Array
(
[hiphop] => Array
(
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
[dubstep] => Array
(
)
[reggae] => Array
(
)
[trap] => Array
(
)
[rnb] => Array
(
[0] => 2123
[1] => 5683
[2] => 2345
[3] => 4567
)
)
You can use uksort for that, which lets you sort by key, based on a user supplied comparison function. Using that function, you can make a function yourself, so you can hide the complex functionality in an easy one.
For instance, you want a function like ksort, only you want to specify an external array of keys, so such a function could look like this:
bool ksort_ext(&$array, $keys)
For the implementation, you can wrap uksort, like so:
function ksort_ext(&$array, $keys)
{
return uksort($array, function($a, $b) use ($keys) {
// Result of callback is based on the position of $a and $b in $keys
return array_search($a, $keys) - array_search($b, $keys);
});
}
Then, you can call it like you would call other sort functions, only with the external array of keys as a second parameter.
$array1 = array(
'hiphop' => array(1,2,3),
'rnb' => array(1,2,3),
'dubstep' => array(1,2,3),
'reggae' => array(1,2,3),
'trap' => array(1,2,3));
$array2 = array('hiphop', 'dubstep', 'reggae', 'trap', 'rnb');
var_dump(ksort_ext($array1, $array2)); // Should return true
var_dump($array1); // Should display the ordered array,

Check values of sub-arrays, use key as new value in new array - PHP

I have an array, let call it $mainArray, which looks like this: -
Array
(
[1] => Array
(
)
[5] => Array
(
[0] => 10
[1] => 15
[2] => 20
[3] => 25
)
[80] => Array
(
[0] => 20
[1] => 40
[2] => 50
[3] => 60
)
[777] => Array
(
[0] => 100
[1] => 200
[2] => 300
[3] => 400
)
[666] => Array
(
[0] => 1234
[1] => 5678
[2] => 20
[3] => 9865
)
[555] => Array
(
[0] => 111
[1] => 222
[2] => 333
[3] => 444
)
)
What I want to do is create 2 new arrays: -
1) Where values are equal to the key names of $mainArray, but only those where the sub-array (if there is one) contains the value "20" somewhere in it. For example my new array (call it $arrayOne) will be [0] => 5, [1] => 80, [2] => 666.
2) Similar to above, but where there's either no sub-array or, if there is, it doesn't include "20" as a value. So that (call it $arrayTwo) would be [0] => 1, [1] => 777, [2] =>555.
I've tried loads of for each loops and even a little RecursiveIteratorIterator (whatever that is!) but can't seem to reference keys and values in the way that I need to. Any help would be much appreciated!
Will this do?:
<?php
foreach( $mainArray as $mKey => &$mVal )
{
if( in_array( 20, $mVal ) )
{
$arrayOne[] = $mKey;
}
else
{
$arrayTwo[] = $mKey;
}
}
I trust you can create a function which would check if array contains 20 as it's value or not. Let's call this function has20.
You two new arrays would then be array_filter($mainArray, 'has20') and array_filter($mainArray, function ($x) {return !has20($x);})
You can do it like this:
$newArray = array();
foreach($mainArray as $key => $subArray) {
if (in_array(20, $subArray)) {
$newArray[] = $key;
}
}

Opposite function of strpos to grab values that do not match a specific pattern in a string or array

What is a function I can use that's basically the opposite of doing
if(strpos($array['some_key'], $value)!==false) {
that means there's a match and confinue
}
I basically want to loop through two arrays and grab the ones that don't have a match to the $value in $array.
$array =
Array
(
[0] => GPPZ20
[1] => GPPZ45
[2] => GPPZ75
[3] => GPPZH20
[4] => GPPZH45
)
$codes =
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH20SWYE4A2VZU
[amount] => 20
)
)
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH2077434178J6
[amount] => 20
)
)
Array
(
[0] => Array
(
[count] => 17
[code] => PMMC4
[amount] => 25
)
)
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH2052910M8V62
[amount] => 20
)
)
Array
(
[0] => Array
(
[count] => 1
[code] => GPPZH45B3116LD1VW
[amount] => 45
)
)
so what i want to do is grab all the ones in the $codes array where the $codes['code'] value does not match any of the ones in the $array value.
right now i have the ones that match and grabbing those by doing
foreach($codes as $code) {
foreach($array as $key=>$value) {
if(strpos($code['code'], $value)!==false) {
//it matches grab those values
}
}
}
I basically now need something like this to grab the ones that do not match
You should use array_filter function - http://php.net/manual/en/function.array-filter.php e.g.:
function myFilter($val){ return strpos('foo', $val) === false; }
$array = array("foobar", "foo", "bar");
var_dump(array_filter($array, myFilter));
You can also use preg_match method instead of strpos.

Categories