i have this array
$items = Array (
[0] => Array ( [0] => xx [1] => 'update')
[1] => Array ( [0] => bx [1] => 'update')
[2] => Array ( [0] => xx [1] => 'creation')
[3] => Array ( [0] => fs [1] => 'creation')
[4] => Array ( [0] => tx [1] => 'update')
[5] => Array ( [0] => bx [1] => 'creation')
)
i'm trying to remove duplicate values based on the first element (xx,bx,ax etc)
if two elements from the same table match, i'd like to keep the last one with higher index,
the result would be like the following
$items = Array (
[0] => Array ( [0] => xx [1] => 'creation')
[1] => Array ( [0] => bx [1] => 'creation')
[2] => Array ( [0] => fs [1] => 'creation')
[3] => Array ( [0] => tx [1] => 'update')
)
keeping the last one was a bit confusing to me as i'm new to PHP.
Thank you in advance
Generic deduplication:
$result = [];
foreach ($array as $item) {
$result[$item[0]] = $item;
}
Functional:
$result = array_reduce($array, function ($acc, $i) {
return [$i[0] => $i] + $acc;
}, [])
Awesome:
array_column($array, null, 0);
Well, i found the solution,
i started bu reversing the array, then executed the following code
$taken = array();
$reverse = array_reverse($items, true);
foreach($reverse as $key => $item) {
if(!in_array($item[0], $taken)) {
$taken[] = $item[0];
} else {
unset($reverse[$key]);
}
}
Related
$routes array:
[admin/login] => Array
(
[0] => POST|AJAX
[1] => admin/login
[2] => admin/login
)
[admin/logout] => Array
(
[0] => POST
[1] => admin/logout
[2] => admin/logout
)
[admin/dashboard] => Array
(
[0] => GET
[1] => admin/dashboard
[2] => admin/dashboard
)
[admin/products] => Array
(
[0] => GET
[1] => admin/products/[:pag]
[2] => admin/products/all
)
[admin/products/add] => Array
(
[0] => GET
[1] => admin/product/add
[2] => admin/products/add
)
[admin/products/insert] => Array
(
[0] => POST
[1] => admin/product/insert
[2] => admin/products/insert
)
[admin/products/show] => Array
(
[0] => GET
[1] => admin/product/[i:id]
[2] => admin/products/show
)
[admin/products/edit] => Array
(
[0] => GET
[1] => admin/product/[i:id]/edit
[2] => admin/products/edit
)
[admin/products/update] => Array
(
[0] => POST
[1] => admin/product/update
[2] => admin/products/update
)
[admin/products/delete] => Array
(
[0] => POST
[1] => admin/product/delete
[2] => admin/products/delete
)
[admin/categories] => Array
(
[0] => GET
[1] => admin/categories
[2] => admin/categories/all
)
[admin/categories/add] => Array
(
[0] => GET
[1] => admin/category/add
[2] => admin/categories/add
)
[admin/categories/insert] => Array
(
[0] => POST
[1] => admin/category/insert
[2] => admin/categories/insert
)
[admin/categories/show] => Array
(
[0] => GET
[1] => admin/category/[i:id]
[2] => admin/categories/show
)
[admin/categories/edit] => Array
(
[0] => GET
[1] => admin/category/[i:id]/edit
[2] => admin/categories/edit
)
[admin/categories/update] => Array
(
[0] => POST
[1] => admin/category/update
[2] => admin/categories/update
)
[admin/categories/delete] => Array
(
[0] => POST
[1] => admin/category/delete
[2] => admin/categories/delete
)
[admin/api] => Array
(
[0] => GET
[1] => admin/api
[2] => admin/api/all
)
[admin/filter/sessions] => Array
(
[0] => POST|AJAX
[1] => admin/filter/sessions
[2] => admin/filters/sessions
)
This is $admin_routes array (build from $routes):
[login] => Array
(
[0] => admin/login
)
[logout] => Array
(
[0] => admin/logout
)
[dashboard] => Array
(
[0] => admin/dashboard
)
[products] => Array
(
[0] => admin/products
[1] => admin/products/add
[2] => admin/products/insert
[3] => admin/products/show
[4] => admin/products/edit
[5] => admin/products/update
[6] => admin/products/delete
)
[api] => Array
(
[0] => admin/api
)
[filter] => Array
(
[0] => admin/filter/sessions
)
[categories] => Array
(
[0] => admin/categories
[1] => admin/categories/add
[2] => admin/categories/insert
[3] => admin/categories/show
[4] => admin/categories/edit
[5] => admin/categories/update
[6] => admin/categories/delete
)
I need some help from you guys about $admin_routes.
I want to combine all sub-arrays from $admin_routes, from same area, which has only one element, in a new sub-array with key name formed from their key names.
Also i want the new sub-array to have same 'position' in line.
My imperfect solution:
// creating $admin_routes
$admin_routes = [];
foreach ($routes as $name => $route) {
if (preg_match('/^admin\/(.*)$/', $name))
$admin_routes[explode('/', $name)[1]][] = $name;
}
// imperfect solution for what i want
$single = false;
$waiting = [];
foreach ($admin_routes as $section => $routes) {
if (count($routes) == 1) { // remember all sub-arrays, with one single element, from same area
$single = true;
$waiting[$section] = $routes;
}
else if ($single) { // if found all sub-arrays, with one single element, from same area
$name = '';
$subarray = [];
foreach ($waiting as $section => $routes) {
// creating only one sub-array
$name .= ($section . ' ');
$subarray = array_merge($subarray, $routes);
unset($admin_routes[$section]);
}
// the problem is, sub-array it's added at the end of $admin_routes
// (not where sub-array's elements were before)
$admin_routes[$name] = $subarray;
$single = false;
$waiting = [];
}
}
The problem is, the new sub-arrays are placed at the end.
If you have any idea, please help me. Thx.
Using your actual result $admin_routes, you could loop through them and rebuild the desired array:
$real_routes = []; // The new array
$singles_key = ''; // The key for combined sub-arrays
$singles_routes = []; // The routes for combined sub-arrays
foreach ($admin_routes as $name => $r) {
/* If this route array has a single entry,
add its name and value to our temp vars */
if (count($r) === 1) {
$singles_key .= $name . ' ';
$singles_routes = array_merge($singles_routes, $r);
} else {
/* If then a route array has multiple value,
save the combined singles and then save this one */
if (!empty($singles_key)) {
$real_routes[trim($singles_key)] = $singles_routes;
$singles_key = '';
$singles_routes = [];
}
$real_routes[$name] = $r;
}
}
/* If the loop ends but the temp vars aren't empty,
save the lasts combined singles */
if (!empty($singles_key)) {
$real_routes[trim($singles_key)] = $singles_routes;
}
// Then to output:
echo '<pre>' . print_r($real_routes, true) . '</pre>';
I have a multi-dimensional array. Since the value of the string "volvo" is present twice, I want to combine those keys. Here's the source array:
Array
(
[0] => Array
(
[0] => Volvo
[1] => 22
)
[1] => Array
(
[0] => BMW
[1] => 15
)
[2] => Array
(
[0] => Saab
[1] => 5
)
[3] => Array
(
[0] => Volvo
[1] => 17
)
)
and I'd like to convert it to this one:
Array
(
[0] => Array
(
[0] => Volvo
[1] => 39
)
[1] => Array
(
[0] => BMW
[1] => 15
)
[2] => Array
(
[0] => Saab
[1] => 5
)
)
I think this would make more sense to return an associated array, that way you can do $arr["volvo"], if you're fine with an associated array, just remove the second foreach loop.
If not, this will get the correct output:
<?php
$arr = Array (
Array (
"Volvo",
22
),
Array (
"BMW",
15
),
Array (
"Saab",
5
),
Array (
"Volvo",
17
)
);
$tmpNewArr = Array();
foreach ($arr as $ele) {
if (!isset($arr[$ele[0]])) {
$tmpNewArr[$ele[0]] = 0;
}
$tmpNewArr[$ele[0]] += $ele[1];
}
$newArr = [];
foreach ($tmpNewArr as $key => $ele) {
array_push($newArr,[$key,$ele]);
}
var_dump($newArr);
?>
Here's an eval.in:
https://eval.in/766340
$keyValueCars = [];
foreach($cars as $car){
$brand = $car[0];
$total = $car[1];
if(!isset($keyValueCars[$brand])){
$keyValueCars[$brand] = total;
}
else{
$keyValueCars[$brand] += total;
}
}
You could use
array_unique(Your_array, SORT_REGULAR);
Array
(
[content_type] => Array
(
[0] => story
[1] => delhi
[2] => tez
)
[type] => Array
(
[0] => video_id
[1] => subcategory
[2] => story_id
)
[fetch_id] => Array
(
[0] => 32
[1] => 32
[2] => 2
)
[order] => Array
(
[0] => 6
[1] => 4
[2] => 5
)
[label] => Array
(
[0] => dsfs fdsf dsf sdf
[1] => dfsdfs
[2] => sdfsdfsd
)
[link] => Array
(
[0] => fsd fsdf sdf
[1] => fsdfsdfdsf
[2] => fsdfdsfds
)
[record] => Array
(
[0] => 10
[1] => 8
[2] => 12
)
)
Above is the array I have to sort this array in the basis of order field and it should shorted all the fields accordingly like below example.
$arr['order'][0] = 4;
$arr['order'][1] = 5;
$arr['order'][2] = 6;
$arr['type'][0] = 'subcategory';
$arr['type'][1] = 'story_id';
$arr['type'][2] = 'video_id';
and so on.....
You can try this -
$new = array();
// Extract and get the keys as values
$order = array_flip($array['order']);
// sort them according to keys
ksort($order);
// loop through main array
foreach($array as $key => $sub_array) {
// loop through order
foreach ($order as $o) {
// store the new value according to order
$new[$key][] = $sub_array[$o];
}
}
Demo
Some lesser solution:
asort($array['order']);
foreach ($array as $key => $subArray) {
$array[$key] = array_replace($array['order'], $subArray);
}
For reset a key sequence you may just to use array_values().
I'm looking to write a function which creates all permutation of a list of arrays (The list is dynamical). Now I found 2 articles, http://dannyherran.com/2011/06/finding-unique-array-combinations-with-php-permutations/ and Finding cartesian product with PHP associative arrays. But I don't want to store them as multiple arrays, I want to add each array to each possibility so I can use them later.
In fact I want to multiply each array with the other.
For example:
$array = array(
array(
1,
2
),
array(
'A',
'B',
'C'),
array(
'I',
'II')
);
In this form:
Array
(
[0] => Array
(
[0] => 1
[1] => Array
(
[0] => Array
(
[0] => A
[1] => Array
(
[0] => I
[1] => II
)
)
[1] => Array
(
[0] => B
[1] => Array
(
[0] => I
[1] => II
)
)
[2] => Array
(
[0] => C
[1] => Array
(
[0] => I
[1] => II
)
)
)
)
[1] => Array
(
[0] => 2
[1] => Array
(
[0] => Array
(
[0] => A
[1] => Array
(
[0] => I
[1] => II
)
)
[1] => Array
(
[0] => B
[1] => Array
(
[0] => I
[1] => II
)
)
[2] => Array
(
[0] => C
[1] => Array
(
[0] => I
[1] => II
)
)
)
)
)
I think this big example made my problem clear. For this type of array I created a function:
foreach ($array[1] as $value) {
$return1[] = array($value, $array[2]);
}
foreach ($array[0] as $value) {
$return[] = array($value, $return1);
}
print_r($return);
Now I want to create this function inside a recursive function (so it becomes dynamical) but I got stuck. I wanted to pass the amount of arrays to the function and then iterate.
function createTree($array, $loops=3){
$b = $array[$loops-2];
foreach ($b as $v) {
$return[] = array($v, createTree($return, $loops-1));
}
print_r($return);
}
Maybe there is a total other solution to multiply the arrays? But the function which isn't recursive is easy for me, but making it recursive...
Thanks for your help
function createTree($array){
switch(count($array)) {
case 0:
die('Illegal argument.');
case 1:
return $array[0];
default:
$lastArray = array_pop($array);
$subArray = createTree($array);
foreach ($lastArray as $item) {
$return[] = array($item, $subArray);
}
return $return;
}
}
var_dump(createTree(array_reverse($array)));
This question already has answers here:
Merge row data from multiple arrays
(6 answers)
Closed 5 months ago.
here: Transforming array values in elements of a subarray using PHP I asked quite the same, but the arrays were flatter. I tried to adapt the code, but unfortunately without success.
How could I merge following arrays so the second array won't be added after the end of the first array, but each subarray of the first array will receive the correspondent values of subarrays of the second. In other words, I want to merge the subarrays. Here my example:
Array 01:
Array01 (
[0] => Array
(
[0] => 40292633
[1] => 412
)
[1] => Array
(
[0] => 41785603
[1] => 382
)
[2] => Array
(
[0] => 48792980
[1] => 373
)
[3] => Array
(
[0] => 44741143
[1] => 329
))
Array 02:
Array02(
[0] => Array
(
[0] => 3460581
[1] => 1407424B1
[2] => 951753
)
[1] => Array
(
[0] => 3484251
[1] => 1028325B1
[2] => 159357
)
[2] => Array
(
[0] => 3519102
[1] => 0586365A1
[2] => 456654
)
[3] => Array
(
[0] => 3529714
[1] => 1059876A1
[2] => 852258
))
Final array:
finalArray(
[0] => Array
(
[0] => 40292633
[1] => 412
[2] => 3460581
[3] => 1407424B1
[4] => 951753
)
[1] => Array
(
[0] => 41785603
[1] => 382
[2] => 3484251
[3] => 1028325B1
[4] => 159357
)
[2] => Array
(
[0] => 48792980
[1] => 373
[2] => 3519102
[3] => 0586365A1
[4] => 456654
)
[3] => Array
(
[0] => 44741143
[1] => 329
[2] => 3529714
[3] => 1059876A1
[4] => 852258
))
Many thanks in advance!
try this code
function merge_arrays($a1, $a2) {
return array($a1, $a2);
}
$result = array_map("merge_arrays", $a1, $a2);
foreach($result as $nr)
{
$nres[] = array_merge ($nr[0], $nr[1]);
}
Try this:
$result = array();
$keys = array_unique( array_merge(array_keys($arr1), array_keys($arr2)) );
foreach($keys as $key) {
if( !array_key_exists($key, $arr1) ) {
$result[$key] = $arr2;
} else if( !array_key_exists($key, $arr2) ) {
$result[$key] = $arr1;
} else {
$result[$key] = array_merge($arr1[$key], $arr2[$key]);
}
}
It does not assume that both arrays have the same keys.
If you'd like to use array_map, this is an equivalent solution:
$keys = array_unique( array_merge(array_keys($arr1), array_keys($arr2)) );
$result = array_map(function($key) use ($arr1,$arr2) {
if( !array_key_exists($key, $arr1) ) {
return $arr2;
} else if( !array_key_exists($key, $arr2) ) {
return $arr1;
}
return array_merge($arr1[$key], $arr2[$key]);
},
$keys);
If you're sure both arrays have the same keys, you can try this:
$result = array();
foreach($arr1 as $key => $arr1val) {
$result[$key] = array_merge($arr1val, $arr2[$key]);
}