Remove a array from an multidimensional array using object value in laravel - php

i need to remove duplicate array from below array.
first and third arrays are same, consider only "id"
$data = [
[
'id' => 'test_fun%test',
'text' => 'test_fun',
'data-value' => 'test',
],
[
'id' => 'test_fun1%test',
'text' => 'test_fun1',
'data-value' => 'test',
],
[
'id' => 'test_fun%test',
'text' => 'test_fun',
'data-value' => 'test',
'selected' => true
]
];
i'm tried to below code.
-> array_unique($data);
-> array_map("unserialize", array_unique(array_map("serialize", $data)));
Expected Output
$data = [
[
'id' => 'test_fun1%test',
'text' => 'test_fun1',
'data-value' => 'test',
],
[
'id' => 'test_fun%test',
'text' => 'test_fun',
'data-value' => 'test',
'selected' => true
]
];

array_unique is not going to work since you have "selected" in the third array. I agree with the comments that this is quite unclear but to me it seems you're looking for a custom filtration rule, so a plain old foreach is the tool for the job.
<?php
$data = [
[
'id' => 'test_fun%test',
'text' => 'test_fun',
'data-value' => 'test',
],
[
'id' => 'test_fun1%test',
'text' => 'test_fun1',
'data-value' => 'test',
],
[
'id' => 'test_fun%test',
'text' => 'test_fun',
'data-value' => 'test',
'selected' => true
]
];
$filtered = [];
foreach ($data as $row) {
$id = $row['id'];
$selected = $row['selected'] ?? false;
if (isset($filtered[$id])) {
if (!$selected) {
continue;
}
unset($filtered[$id]);
}
$filtered[$id] = $row;
}
// optional use if you don't want ids for keys
$filtered = array_values($filtered);
print_r($filtered);

Related

PHP: Remove duplicate elements and get the latest data in the array

$arr = [
[
"id" => '6230061c0e88d709ca0d7bbc',
'name' => 'Mobile SamSung',
'slug' => 'mobile-samsung',
'createdAt' => '1648006346'
],
[
"id" => '5d1eff529a426778d4b92383',
'name' => 'Mobile Iphone',
'slug' => 'mobile-iphone',
'createdAt' => '1647314181'
],
[
"id" => '5d1eff6b9a426778d4b92dc4',
'name' => 'Mobile SamSung',
'slug' => 'mobile-samsung',
'createdAt' => '1647314460'
],
[
"id" => '5f894011266aea580b028cb0',
'name' => 'Mobile LG',
'slug' => 'mobile-lg',
'createdAt' => '1647314456'
]
];
I have an array, and in this array there are many duplicate subarrays, now I want to remove the duplicate arrays inside, keeping only the data with the latest createdAt. Please give me your opinion. Thanks
I would like to get an array like this:
$arr = [
[
"id" => '6230061c0e88d709ca0d7bbc',
'name' => 'Mobile SamSung',
'slug' => 'mobile-samsung',
'createdAt' => '1648006346'
],
[
"id" => '5d1eff529a426778d4b92383',
'name' => 'Mobile Iphone',
'slug' => 'mobile-iphone',
'createdAt' => '1647314181'
],
[
"id" => '5f894011266aea580b028cb0',
'name' => 'Mobile LG',
'slug' => 'mobile-lg',
'createdAt' => '1647314456'
]
];
You should not make more than one pass over your data. Just use the name values as temporary keys, then only retain a duplicate row's data if its createAt value is greater than what is stored. Re-index the array when you are finished looping.
Code: (Demo)
$result = [];
foreach ($arr as $row) {
if (!isset($result[$row['name']]) || (int)$row['createdAt'] > (int)$result[$row['name']]['createdAt']) {
$result[$row['name']] = $row;
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'id' => '6230061c0e88d709ca0d7bbc',
'name' => 'Mobile SamSung',
'slug' => 'mobile-samsung',
'createdAt' => '1648006346',
),
1 =>
array (
'id' => '5d1eff529a426778d4b92383',
'name' => 'Mobile Iphone',
'slug' => 'mobile-iphone',
'createdAt' => '1647314181',
),
2 =>
array (
'id' => '5f894011266aea580b028cb0',
'name' => 'Mobile LG',
'slug' => 'mobile-lg',
'createdAt' => '1647314456',
),
)
Potentially helpful:
Laravel - fetch unique rows from table having highest value in x column
Remove duplicate objects from array based on one value, keep lowest of other value in PHP?
Filter rows with unique column value and prioritize rows with a particular value in another column
How to get max amount of value in same key in array
Explanation:
In this solution, I have gotten the data with a unique slug key with the latest createdAt key. we can have any unique key that matches into the multidimensional array and get the result whatever we want.
Code:
$newArray = [];
foreach ($array as $key => $value) {
$findIndex = array_search($value['slug'], array_column($newArray, 'slug'));
if ($findIndex === false) {
$newArray[] = $value;
} elseif ($findIndex !== false && $newArray[$findIndex]['createdAt'] <= $value['createdAt']) {
$newArray[$findIndex] = $value;
}
}
print_r($newArray);
Demo Link (With your Data): https://3v4l.org/f4kRM
Demo Link (Customized Data with my way): https://3v4l.org/sj4MW
First sort on created at, then remove duplicates.
<?php
$arr = [
[
"id" => '6230061c0e88d709ca0d7bbc',
'name' => 'Mobile SamSung',
'slug' => 'mobile-samsung',
'createdAt' => '1648006346'
],
[
"id" => '5d1eff529a426778d4b92383',
'name' => 'Mobile Iphone',
'slug' => 'mobile-iphone',
'createdAt' => '1647314181'
],
[
"id" => '5d1eff6b9a426778d4b92dc4',
'name' => 'Mobile SamSung',
'slug' => 'mobile-samsung',
'createdAt' => '1647314460'
],
[
"id" => '5f894011266aea580b028cb0',
'name' => 'Mobile LG',
'slug' => 'mobile-lg',
'createdAt' => '1647314456'
]
];
function sort_objects_by_created($a, $b) {
if($a['createdAt'] == $b['createdAt']){ return 0 ; }
return ($a['createdAt'] > $b['createdAt']) ? -1 : 1;
}
// Let's sort
usort($arr, 'sort_objects_by_created');
$slugs = [];
$result = [];
// Loop object
foreach($arr as $phone) {
// If slug is not found, add to result
if (!in_array($phone['slug'], $slugs)){
$slugs[] = $phone['slug'];
$result[] = $phone;
}
}
var_dump($result,$slugs);
Might be worth a note, that you might be able to improve this upstream when creating your array. (always look upstream!)
If you can give you base array a key of created At you can use Array sorting, which which will this step more effecient....
E.g.
$arr = [];
$arr[2022-01-01] = Array('id' => 123, 'name' = 'abc');
$arr[2022-04-01] = Array('id' => 123, 'name' = 'abc');
$arr[2022-08-01] = Array('id' => 123, 'name' = 'abc');

PHP merge duplicate key in array

i got response (json) from web service and converted / decoded it into php array.
converted array php:
$data = [
[
'id' => '01',
'name' => 'ABC',
'label' => 'color',
'value' => '#000000'
],[
'id' => '01',
'name' => 'ABC',
'label' => 'active',
'value' => true
],[
'id' => '02',
'name' => 'DEF',
'label' => 'color',
'value' => '#ffffff'
],[
'id' => '02',
'name' => 'DEF',
'label' => 'active',
'value' => false
]
];
expected array output:
$data = [
[
'id' => '01',
'name' => 'ABC',
'color' => '#000000',
'active' => true,
],[
'id' => '02',
'name' => 'DEF',
'color' => '#ffffff',
'value' => false
]
];
What php function is suitable for that case? thanks in advance
You can simple use foreach
$r = [];
foreach($data as $v){
if(isset($r[$v['id']])){
$r[$v['id']][$v['label']] = $v['value'];
}else{
$r[$v['id']] = [
'id' => $v['id'],
'name' => $v['name'],
$v['label'] => $v['value']
];
}
}
Live example : https://3v4l.org/ilkGG
$data = json_decode($data); //decode the json into a php array
foreach ($data as $key=>$subArray){ //loop over the array
//check and see if value is either true/false
if (is_bool($subArray['value'])){
$processedArray[] = $subArray; //build output
}
}
print_r($processedArray); //output/dump array for debugging
In this case, you have to loop through the array and remove duplicates, Try the given way
$data = json_decode($data , true);
$filtered = array();
for($i = 0 ; $i < count($data) ; $i++){
if(!array_key_exist($data[$i]['id'] , $filtered )){
$filtered [$data[$i]['id']] = $data[$i];
continue;
}
}
$filtered = array_values($filtered);

Need to push the key and value inside associative Array?

I need to push the more key and its value inside the array. If I use below code first key pair replaced by 2nd one.
For your Reference:
Code Used:
foreach ($projectData['projectsections'] as $key => $name) {
$projectData['projectsections'][$key] = ['name' => $name];
$projectData['projectsections'][$key]= ['id' => '1'];
}
Current result:
'projectsections' => [
(int) 0 => [
'id' => '1'
],
(int) 1 => [
'id' => '1'
]
],
Expected:
'projectsections' => [
(int) 0 => [
'name' => 'test1',
'id' => '1'
],
(int) 1 => [
'name' => 'test2',
'id' => '1'
]
],
How can I build this array in PHP?? Any one help??
You need to either add the entire array:
$projectData['projectsections'][$key] = ['name' => $name, 'id' => '1'];
Or add with the key name:
$projectData['projectsections'][$key]['name'] = $name;
$projectData['projectsections'][$key]['id'] = '1';
With
$projectData['projectsections'][$key] = ['name' => $name];
$projectData['projectsections'][$key]= ['id' => '1'];
you are setting a new Array for that $key. This is not what you want.
This should work:
$projectData['projectsections'][$key] = ['name' => $name, 'id' => '1'];
Change it to :
foreach ($projectData['projectsections'] as $key => $name) {
$projectData['projectsections'][$key]['name'] = $name;
$projectData['projectsections'][$key]['id'] = '1';
}

Recursively insert element next to other element in array

I have a multidimensional array that may or may not contain the key name one or more times. What I'd like to do is for every instance of said element insert another element, next to that element, with the key key.
So, given this array:
[
[
'noname' => 'No name',
'label' => 'I have no name'
],
[
'name' => 'foo',
'label' => 'Foo',
'fields' => [
[
'name' => 'bar',
'label' => 'Bar'
]
]
],
[
'name' => 'baz',
'label' => 'Baz'
]
]
I'd like the following output:
[
[
'noname' => 'No name',
'label' => 'I have no name'
],
[
'name' => 'foo',
'key' => 'foo-key', # This is inserted by the function
'label' => 'Foo',
'fields' => [
[
'name' => 'bar',
'key' => 'bar-key', # This is inserted by the function
'label' => 'Bar'
]
]
],
[
'name' => 'baz',
'key' => 'baz-key', # This is inserted by the function
'label' => 'Baz'
]
]
I've looked into array_walk_recursive but can't get it to work. Do I need to write my own recursive function or is there something appropriate built in that I can use for this?
Your code would be something like this:
<?php
$array = [
[
'noname' => 'No name',
'label' => 'I have no name'
],
[
'name' => 'foo',
'label' => 'Foo',
'fields' => [
[
'name' => 'bar',
'label' => 'Bar'
]
]
],
[
'name' => 'baz',
'label' => 'Baz'
]
];
function fix_array($array){
foreach ($array as $key => $value){
if (is_array($value)){
$array[$key] = fix_array($value);
}
elseif ($key == 'name'){
$array['key'] = $value . '-key';
}
}
return $array;
}
$new_array = fix_array($array);
print_r($new_array);

Recursively Create an Array from another Array

I am trying to make a multi-dimensional array build an array path adding the hr field so it looks like this:
I just can't figure out how to add the totals, nor create a sub-array so the dot notation in an option too. My goal is to get something like this:
[1] => [1][2][1][5][0][6] = 35 (the second child path "1")
[1] => [1][2][1][5][0][7] = 25
or Something like this:
array (
[children.0.children.0.children.0.total] = 20
[children.0.children.1.children.1.total] = 35
// etc
)
The complicated part is that it goes in different directions and I want to know what is the highest and lowest total based on the path:
==> Run Code Here or Copy/Paste
// -------------
// The Flattener
// -------------
function doit($myArray) {
$iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray));
$result = array();
foreach ($iter as $leafKey => $leafValue) {
$keys = array();
foreach (range(0, $iter->getDepth()) as $depth) {
$keys[] = $iter->getSubIterator($depth)->key();
}
$result[ join('.', $keys) ] = $leafValue;
}
return $result;
}
// -------------
// Example Tree
// -------------
$tree = [
'id' => 1,
'type' => 'note',
'data' => [],
'children' => [
[
'id' => 2,
'type' => 'wait',
'data' => [
'hr' => 10,
],
'children' => [
[
'id' => 3,
'type' => 'wait',
'data' => [
'hr' => 10,
],
'children' => [
'id' => 4,
'type' => 'exit',
'data' => [],
'children' => []
]
],
[
'id' => 5,
'type' => 'note',
'data' => [
'hr' => 10,
],
'children' => [
[
'id' => 6,
'type' => 'wait',
'data' => [
'hr' => 10,
],
'children' => []
],
[
'id' => 7,
'type' => 'exit',
'data' => [],
'children' => []
],
]
]
],
]
]
];
$result = doit($tree);
print_r($result);
This seems to work, I found it somewhere googling all day.
array_reduce(array_reverse($keys), function($parent_array, $key) {
return $parent_array ? [$key => $parent_array] : [$key];
}, null);

Categories