php sort array within array by matching keys - php

I searched for my related topic, but didn't find a similar issue.
I have an array within an array and I have an array which I define as my ordering array.
[array1] => Array
(
[23456] => Array
(
[id] => 1
[info] => info
)
[78933] => Array
(
[id] => 1
[info] => info
)
)
and so on....
[orderarray] => Array
(
[0] => Array
(
[id] => 78933
)
[1] => Array
(
[id] => 23456
)
)
I would like to reorder array1 keys by the value of orderarray id.
So the first key should be then 78933 and not like in array1 23456.
Does anybody knows how to continue this?
I know to read the keys from array1.
foreach ($array1 as $key)
{
echo $key;
}
foreach ($orderarray as $key)
{
foreach ($key as $id => val)
{
echo $val;
}
}
So how can I merge both foreach together the best way?
Thank you so much!

You can use a custom key-sort function using uksort()
<?php
$array = array(
"23456" => array("id" => 1, "info" => "info"),
"78933" => array("id" => 1, "info" => "info")
);
$orderarray = array(
array("id" => 78933),
array("id" => 23456)
);
function customSort($a, $b) {
global $orderarray;
$_a = 0; $_b = 0;
foreach ($orderarray as $index => $order) {
$oid = intval($order['id']);
if ($oid == intval($a)) $_a = $index;
if ($oid == intval($b)) $_b = $index;
}
if ($_a == $_b) {
return 0;
}
return ($_a < $_b) ? -1 : 1;
}
uksort($array, "customSort");
print_r($array);
?>

Related

Simplify Array Duplicate Element in Array PHP

How can we find the count of duplicate elements in a multidimensional array,
I have an array like this:
Array
(
[0] => Array
(
[brti] => 29
)
[1] => Array
(
[voda] => 6
)
[2] => Array
(
[btel] => 8
)
[3] => Array
(
[btel] => 10
)
)
Question: How to simplify the structure of array, i mean can be counting the value if there is indicate that have same key ?
just like this:
Array
(
[0] => Array
(
[brti] => 29
)
[1] => Array
(
[voda] => 6
)
[2] => Array
(
[btel] => 18
)
)
So far, i've tried this way, but it didn't help me. My array is store in $test
$test = [sample array]
$count = array();
foreach ($test as $key => $value) {
foreach ($value as $k => $val) {
if (isset($count[$val])) {
++$count[$val];
} else {
$count[$value] = 1;
}
}
}
print_r($count);
<?php
$array = [
"0" => ["brti" => 29],
"1" => ["voda" => 6],
"2" => ["btel" => 8],
"3" => ["btel" => 10],
];
$final = array();
array_walk_recursive($array, function($item, $key) use (&$final){
$final[$key] = isset($final[$key]) ? $item + $final[$key] : $item;
});
print_r($final);
});
check demo
You can do it in very simple way,
$test = [];
foreach ($array as $value)
{
foreach ($value as $k => $v)
{
// $test[$k] = ($test[$k] ?? 0); // initialised if not php 7+
$test[$k] = (empty($test[$k]) ? 0: $test[$k]); // below php 7
$test[$k] += $v;
}
}
print_r($test);
Output:
Array
(
[brti] => 29
[voda] => 6
[btel] => 18
)
Working demo.

Get the unique array from an array with the lowest number

im having trouble figuring this one out, the scenario is, that there is an multidimensional array, in which there is name, id, and number in an array, what i want is to get the unique array in which array having same name should not appear, this can be done and i had done it, but i also want that the array that is returned should contain the lowest num, i hope this would help make you understand
i have
Array(
[0]=>array(
[id]=>1
[name]=>abc
[num]=>4)
[1]=>
array(
[id]=>2
[name]=>efg
[num]=>4)
[2]=>array(
[id]=>3
[name]=>abc
[num]=>2)
)
Now its a rough array representation, what i want from this is
Array(
[0]=>array(
[id]=>3
[name]=>abc
[num]=>2)
[1]=>
array(
[id]=>2
[name]=>efg
[num]=>4)
What im using:
code.php
<?php
$details = array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"9876543210"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
2 => array("id"=>"1", "name"=>"Mathew", "num"=>"784581254"),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$details = unique_multidim_array($details,'name');
?>
This function returns me
Array(
[0]=>array(
[id]=>1
[name]=>abc
[num]=4)
[1]=>
array(
[id]=>2
[name]=>efg
[num]=>4)
You can use array_reduce:
$result = array_reduce
(
$array,
function( $carry, $item )
{
if( !isset( $carry[$item['name']] ) || $item['num'] < $carry[$item['name']]['num'] )
{
$carry[$item['name']] = $item;
}
return $carry;
},
[] // This parameter (empty array) is optional in this case
);
$result = array_values( $result );
We compare each array element with constructing returned array (initially empty): if in returned array doesn't exists an item with key = $item['name'], we add it; otherwise, if current item has num value lower than corresponding returned array item, we replace this item with current item. At the end, we use array_values to remove associative keys.
Result:
Array
(
[0] => Array
(
[id] => 3
[name] => abc
[num] => 2
)
[1] => Array
(
[id] => 2
[name] => efg
[num] => 4
)
)
Read more about array_reduce
Read more about array_values
I would do this with two loops
First, group the values by name, then number
foreach ($your_array as $value) {
$names[$value['name']][$value['num']] = $value;
}
Then iterate the result of that, sort name by key (num) and append the first element to the final result.
foreach ($names as $set_of_nums) {
ksort($set_of_nums);
$result[] = reset($set_of_nums);
}
I have considered the below example.
$details = array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"123"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"235"),
2 => array("id"=>"3", "name"=>"Mike", "num"=>"5"),
3 => array("id"=>"4", "name"=>"Tom", "num"=>"256"),
4 => array("id"=>"5", "name"=>"Tom", "num"=>"500"),
5 => array("id"=>"6", "name"=>"Mike", "num"=>"7"),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$key_array = array();
foreach($array as $k=>$val) {
if (!in_array($val[$key], $key_array)) {
// storing the array with the key
$key_array[$k] = $val[$key];
$temp_array[$k] = $val;
} else{
foreach($key_array as $r=>$p){
//check for the array with the name
if($temp_array[$r]['name'] == $val['name']){
// compare the value
if($temp_array[$r]['num']>$val['num']){
// store the new array to the temp_array with same key of key_array
$temp_array[$r] = $val;
}
}
}
}
}
return $temp_array;
}
$details = unique_multidim_array($details,'name');
Output:
Array
(
[0] => Array
(
[id] => 3
[name] => Mike
[num] => 5
)
[1] => Array
(
[id] => 2
[name] => Carissa
[num] => 235
)
[3] => Array
(
[id] => 4
[name] => Tom
[num] => 256
)
)
You can sort the output array using any of the sort functions as you desire.

PHP - Get value from keys in multidimensional array

Here is my array
$myArray = Array(
[63145] => Array
(
[id] => 63145
[name] => banana
[type] => fruit
)
[244340] => Array
(
[id] => 244340
[name] => apple
[type] => fruit
)
[253925] => Array
(
[id] => 253925
[name] => portato
[type] => vegetable
)
[233094] => Array
(
[id] => 233094
[name] => carrot
[type] => vegetable
));
How do i loop through this and pull out the ids of all fruits, so i kan use them in another foreach loop?
maybe with a If statement, so that if(type == fruit) use the ids in the foreach loop.
I have tried to look through other questions but I can't figure out how to convert the answers to my array (I know I'm a noob)..
The naïve:
$fruitIds = [];
foreach ($myArray as $item) {
if ($item['type'] == 'fruit') {
$fruitIds[] = $item['id'];
}
}
The functional:
$fruitIds = array_column(
array_filter($myArray, function (array $i) { return $i['type'] == 'fruit'; }),
'id'
);
The more efficient functional:
$fruitIds = array_reduce($myArray, function (array $ids, array $i) {
return array_merge($ids, $i['type'] == 'fruit' ? [$i['id']] : []);
}, []);
You can do this using PHP's array_column and array_filter:
$fruit_ids = array_column(array_filter($arr, function($item, $index) {
return $item['type'] == 'fruit';
}), 'id');
But also your array keys seem to be the same as your id values on the child arrays, so you could mix array_filter with array_keys:
$fruit_ids = array_keys(array_filter($arr, function($item, $index) {
return $item['type'] == 'fruit';
}));

Splitting keys from values into another array

I have a function to convert a .json file to an array:
function jsonToArray($file) {
$json = json_decode(file_get_contents($file), true);
print_r($json); }
This yields an array like this:
Array (
[field1] => value1
[field2] => Array
(
[subfield1] => subvalue1
[subfield2] => subvalue2
[subfield3] => subvalue3
)
)
To interface with existing code, I need these arrays with the fields and values split, like this:
Array (
[0] => Array
(
[0] => field1
[1] => Array
(
[0] => subfield1
[1] => subfield2
[2] => subfield3
)
)
[1] => Array
(
[0] => value1
[1] => Array
(
[0] => subvalue1
[1] => subvalue2
[2] => subvalue3
)
)
)
The code I came up with works if this structure is maintained for all usage but as that can't be guaranteed I need another solution. I'm sure it's something relatively simple, I just can't crack it. Any hints or insight would be much appreciated.
try this code
$arr = array ('field1' => 'value1',
'field2' => array(
'subfield1' => 'subvalue1',
'subfield2' => 'subvalue2',
'subfield3' => 'subvalue3'));
function array_values_recursive($ary) {
$lst = array();
foreach( $ary as $k => $v ) {
if (is_scalar($v)) {
$lst[] = $v;
} elseif (is_array($v)) {
$lst[] = array_values_recursive($v);
}
}
return array_values($lst);
}
function array_keys_recursive($ary) {
$lst = array();
foreach( $ary as $k => $v ) {
if (is_scalar($v)) {
$lst[] = ($k);
} elseif (is_array($v)) {
$lst[] = array_keys_recursive($v);
}
}
return $lst;
}
echo '<pre>';
$arr1 = array();
$arr1[] = array_values_recursive($arr);
$arr1[] = array_keys_recursive($arr);
print_r($arr1);
This might be useful to you: array_values() and array_keys() that and a little of foreach would do the magic.

Find the difference from two arrays in php

--$arr1----
Array
(
[0] => Array
(
[id] => 1
[Name] => AAA
)
[1] => Array
(
[id] => 6
[Name] => BBB
)
)
--$arr2---
Array
(
[0] => Array
(
[id] => 1
[Name] => AAA
)
[1] => Array
(
[id] => 6
[Name] => BBB
)
[2] => Array
(
[id] => 46
[Name] => CCC
)
)
I would like the final result as following. Is there anyone can help me?
--Final Result--
Array
(
[0] => Array
(
[id] => 46
[Name] => CCC
)
)
UPDATE---
In this case, the result of array_diff($arr1,$arr2) is empty.
The easiest way is Mark Baker's solution or just write your own simple function:
Code:
function arrdiff($a1, $a2) {
$res = array();
foreach($a2 as $a) if (array_search($a, $a1) === false) $res[] = $a;
return $res;
}
print_r(arrdiff($arr1, $arr2));
Output:
Array
(
[0] => Array
(
[id] => 46
[name] => CCC
)
)
$arr1 = array(array('id' => 1, 'Name' => 'AAA'),
array('id' => 6, 'Name' => 'BBB')
);
$arr2 = array(array('id' => 1, 'Name' => 'AAA'),
array('id' => 6, 'Name' => 'BBB'),
array('id' => 46, 'Name' => 'CCC')
);
$results = array_diff(array_map('serialize',$arr2),array_map('serialize',$arr1));
$results = array_map('unserialize',$results);
var_dump($results);
EDIT
And just for the sheer fun of it, you could use array_filter() instead of array_diff() - which means no need to serialize anything at all
$results = array_filter($arr2, function ($value) use($arr1) { return !in_array($value,$arr1); } );
var_dump($results);
You should use array_diff():
$finalResult = array_diff($arr2, $arr1);
If you need more complex comparison you may also build foreach loop and use like this:
function compareItems( $a, $b){
return $a['id'] == $b['id']; // Example compare criteria
}
$result = array();
foreach( $arr1 as $item){
foreach( $arr2 as $key => $it){
if( !compareItems( $item, $it)){
$result[] = $it; // Either build new array
unset( $arr2[$key]); // Or remove items from original array
break;
}
}
}
And than you'll probably want to implement the same with reversed order of $arr1 and $arr2.
You can solve this with array_udiff()
function arr_comp($a, $b)
{
if ($a['id'] == $b['id'])
return 0;
else if ($a['id'] > $b['id'])
return 1;
else
return -1;
}
$result = array_udiff($arr2, $arr1, 'arr_comp');
or if you don't know in which array the differences may be you can try:
$res1 = array_udiff($arr1, $arr2, 'arr_comp');
$res2 = array_udiff($arr2, $arr1, 'arr_comp');
$result = array_merge($res1, $res2);
$arrDif=array();
$i=0;
foreach($arr1 as $value)
{
if(!in_array($value, $arr2))
{
$arrDif[$i]=$value;
$i++;
}
}
Take a look at the PHP built-in function array_diff. That'll help you out :-) Just pass your two arrays, and store the array returned by array_diff(), which will contain the differences between the two arrays.
As you're using multi-dimensional arrays, look at this comment on the PHP website: http://www.php.net/manual/en/function.array-diff.php#98680.

Categories