How to remove unique elements within multidimensional array? - php

How to remove dulicate keys from multidimensional array?
My array is as follows:
$array = [[0, 1, 2, 3, 4], [1, 2, 3, 4, 6]];
My desired array should be:
$array = [[0, 1, 2, 3, 4], [6]];

Here's a quick and dirty solution for you:
Walk through every element of the array recursively and if you've not seen an element set it to null (unsetting it doesn't work for some reason). Then filter the resulting sub-arrays.
$array = [[0, 1, 2, 3, 4], [1, 2, 3, 4, 6]];
$seen = [];
array_walk_recursive($array, function (&$v) use (&$seen) {
if (!array_key_exists($v, $seen) {
$seen[$v] = true;
} else {
$v = null;
}
});
$final = array_map('array_filter', $array);

If the functions array_diff() and array_values​​() are used, the solution can be delivered in one line of code:
$array = [[0, 1, 2, 3, 4], [1, 2, 3, 4, 6]];
$array[1] = array_values(array_diff($array[1],$array[0]));
var_export($array);
Output:
array (
0 =>
array (
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
),
1 =>
array (
0 => 6,
),
)

$serialize=array_map('serialize',$array);
$unique=array_unique($serialize);
$result=array_map('unserialize',$uniue);
print_r($result);

Related

How to get max element at each index while comparing two arrays?

I have two indexed arrays of identical length:
$first_array = [1,3,4,5,6];
$second_array = [5,2,1,7,9];
I need to generate a new array that consists of the higher value between the two elements at each index.
The output should be:
$output_array[5, 3, 4, 7, 9];
Super easy one-liner:
Pass both arrays to array_map(), as it synchronously loops through both sets of data, call max() on the two elements.
Code: (Demo)
$first_array = [1, 3, 4, 5, 6];
$second_array = [5, 2, 1, 7, 9];
var_export(array_map('max', $first_array, $second_array));
Output:
array (
0 => 5,
1 => 3,
2 => 4,
3 => 7,
4 => 9,
)
Try this way. demo
<?php
$first_array = array(1,3,4,5,6);
$second_array = array(5,2,1,7,9);
$return = array();
foreach($first_array as $key => $value){
if($first_array[$key] > $second_array[$key]){
$return[] = $first_array[$key];
}else{
$return[] = $second_array[$key];
}
}
print_r($return);

Sort an array of numbers by another predefined, non-exhaustive array of number, then sort ascending

Given two arrays $A1 and $A2, sort $A1 in such a way that the relative order among the elements will be same as those in $A2. For the elements not present in $A2, move them to the back of the array in ascending order.
$A1 = [2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8];
$A2 = [2, 1, 8, 3];
Desired output:
[2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9]
Coding attempt:
$sorted = array();
foreach($a1 as $key => $value) {
if(in_array($value, $a2)) {
$sorted[array_search($value, $a1)] = $value;
}
}
This can be done via for each loop :
$arr1 = array(2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8); // array to be sorted
$arr2 = array(2, 1, 8, 3); // refrence array for sort logic
// Output: A1[] = {2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9}
$sortarr = array(); // array to store final sorted values
foreach ($arr2 as $a) {
foreach ($arr1 as $k => $b) {
if($b==$a) {
$sortarr[]=$b;
unset($arr1[$k]);
}
}
}
$finalarr = array_merge($sortarr, $arr1);
print_r($finalarr);
You can use usort like this:
$k = array_flip($a2); // Create an associative array for the second array
usort($a1, function($a, $b) use ($k) {
return isset($k[$a]) ? (isset($k[$b]) ? $k[$a]-$k[$b] : -1) : (isset($k[$b]) ? 1 : $a-$b);
});
Other solutions that use a nested loop result in a time complexity of O(n²), while this has a time complexity of O(nlogn).
i tried this code and works:
<?php
/*
Input: A1[] = {2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8}
A2[] = {2, 1, 8, 3}
Output: A1[] = {2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9}
*/
$a1=array(2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8);
$a2=array(2, 1, 8, 3);
$a3=array();
sort($a1);//order array
//order array a3 with a2 value....
for($i=0;$i<sizeof($a2);$i++){
for($j=0;$j<sizeof($a1);$j++){
if($a1[$j]==$a2[$i]){
array_push($a3,$a2[$i]);
//if exsist value i change value in a1 in x
$a1[$j]="x";
}
}
}
//write in a3 the next number not present in a2
for($i=0;$i<sizeof($a1);$i++){
if($a1[$i]<>"x"){
array_push($a3, $a1[$i]);
}
}
print_r($a3);
//out:Array ( [0] => 2 [1] => 2 [2] => 1 [3] => 1 [4] => 8 [5] => 8 [6] => 3 [7] => 5 [8] => 6 [9] => 7 [10] => 9 )
?>
Hope this helps
I do not endorse the use of nested loops because they will be doing too many unnecessary cycles. #trincot's approach moreso represents what I would use in a professional application, but I will demonstrate a more modern and concise style with no iterated function calls.
Code: (Demo)
$arr1 = [2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8];
$arr2 = [2, 1, 8, 3];
$priority = array_flip($arr2);
$fallback = count($arr2);
usort(
$arr1,
fn($a, $b) =>
[$priority[$a] ?? $fallback, $a]
<=>
[$priority[$b] ?? $fallback, $b]
);
var_export($arr1);
// [2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9]
$arr2 is flipped into a lookup array, and count() is used when a value is not found in the lookup array. Whenever the first rule results in a tie, the second rule orders the numbers numerically in an ascending direction.
The meaning of custom function's syntax is:
[left value rule1, left value rule2] compared to [right value rule1, right value rule2]
The spaceship operator (<=>) will compare the corresponding element one at a time "rule1 vs rule1" then "rule2 vs rule2" as needed.

Add value from one element to other in php

This is probably a duplicate, but I couldn't find the answer I needed, maybe my wording is wrong.
Anyway, I have a two-dimensional array with hundreds of values, what I need is to insert a value from second element to the first element.
Example;
I have four elements in an array:
[0] = 1, [1] = 9, [2] = 9, [3] =5
I need to put these into a single element, so that it would turn
into this: [0] = 1995.
I have a feeling there might be something I could do with foreach, if so, maybe someone can explain to me, in detail, how that would exactly work?
OR
Maybe there's a function I'm not aware of.
You can use the following, using implode:
$arr = [1, 9, 9, 5];
$val = implode($arr);
unset($arr);
$arr[0] = $val;
demo: https://ideone.com/VTb7vO
To use the solution using implode on the whole multidimensional array, you can use the following:
$arr = [[1, 9, 9, 5], [1, 9, 9, 6], [1, 9, 9, 7], [1, 9, 9, 8]];
foreach ($arr as $key => $value) {
$val = implode($value);
$arr[$key] = $val;
}
demo: https://ideone.com/X6vueO
another, much shorter solution could be the following:
$arr = [[1, 9, 9, 5], [1, 9, 9, 6], [1, 9, 9, 7], [1, 9, 9, 8]];
$arr = array_map('implode', $arr);
demo: https://ideone.com/0ju8he
To concatenate each inner array of numbers you can use implode on each of it.
$newArray = array_map('implode', $array);
If it is executed on the array [[1, 2, 3], [1, 3], [1, 1, 1]] it will create the array ['123', '13', '111']. demo
$arr = [2,3,4];
$var = implode($arr, '');
var_dump( $var );
Two dimensional:
$cars = array
(
array(22,18),
array(15,13),
array(5,2),
array(17,15)
);
foreach ($cars as $val) {
$var1 = implode($val, '');
var_dump( $var1 );
}
$var= "";
foreach($arr as $element) {
$var .= $element;
}

PHP compare arrays

I have two arrays. $arrayOld and $arrayNew and I want to compare these arrays and only select the values that are not in $arrayNew.
I don't want the values that are in $arrayNew only. So I don't think array_diff() is gonna help me.
$arrayOld = [1, 2, 3, 4, 5]
$arrayNew = [1, 4, 5, 6, 7]
So it only needs to return 2 and 3 and not 6 or 7.
use array_diff, to accomplish this. As you need to difference between the array and need data from Old array so you need to use the old array as the first parameter of the array_diff.
Note: Array diff only returns from the first array which is not in second array.
$arrayOld = [1, 2, 3, 4, 5];
$arrayNew = [1, 4, 5, 6, 7];
$n = array_diff($arrayOld, $arrayNew);
print_r($n);
Result: Online Check
Array
(
[1] => 2
[2] => 3
)
If you need a new keys for the output array just use array_values. The new key start from 0.
$arr = array_values($n);
Use below code
$arrayOld = [1, 2, 3, 4, 5];
$arrayNew = [1, 4, 5, 6, 7];
print "<pre>";
print_r(array_diff($arrayOld, $arrayNew));
OUTPUT:
Array
(
[1] => 2
[2] => 3
)
use this code.
$arrayOld = array(1, 2, 3, 4, 5);
$arrayNew = array(1, 4, 5, 6, 7);
print_r(array_diff($arrayOld, $arrayNew));
$compare = array();
$i=1;
foreach($arrayOld as $k=>$v){
if(!in_array($v, $arrayNew)){
$compare[$i] = $v;
$i++;
}
}
$i=$i;
foreach($arrayNew as $k=>$v){
if(!in_array($v, $arrayOld)){
$compare[$i] = $v;
$i++;
}
}
use array_diff function
$arrayOld = array(1, 2, 3, 4, 5);
$arrayNew = array(1, 4, 5, 6, 7);
print_r(array_diff($arrayOld, $arrayNew));

PHP: How to get both key and value from an associative array?

I have this associative array structure:
$multiArray = array(
'key1' => array(1, 2, 3, 4),
'key2' => array(5, 6, 7, 8),
'key3' => array(9, 10, 11, 12)
);
When I call $multiArray['key1'], I get the value (which is normal):
// Example 1
$multiArray['key1'];
//$multiArray only has [1, 2, 3, 4]
Is there a way that when I call I want $multiArray['key1'] that I can have ['key1' => array(1,2,3,4)] or the other two keys, depending on the situation?
I could structure $multiArray like so, but I was wondering if there is a better way.
// Example 2
$multiArray = array(
'keyA' => array('key1' => array(1, 2, 3, 4)),
'keyB' => array('key2' => array(5, 6, 7, 8)),
'keyC' => array('key3' => array(9, 10, 11, 12))
);
$multiArray['keyA'];
// $multiArray is now what I want: ['key1' => [1, 2, 3, 4]]
You could do something like this:
function getArray ($multiArray, $key) {
return array($key => $multiArray[$key]);
}
or
$result = array('key1' => $multiArray['key1']);
A little more context as to how you're using it would be useful though. It sounds like you already know the requested key at the point of use. If not you may need to use array_keys.
I think what you may be looking for is foreach:
$myArray = array('key1' => array(1, 2, 3), 'key2' => array(4, 5, 6));
$multiArray = array();
foreach ($myArray as $key => $value) {
// $key would be key1 or key2
// $value would be array(1, 2, 3) or array(4, 5, 6)
$multiArray[] = array($key => $value);
}

Categories