Make array unique in multidimensional array php codeigniter - php

I have this array
Array (
[0] => Array
(
[0] => stdClass Object
(
[id] => 226
[user_id] => 1
[name] => Eden Corner Tub by Glass - $2099
)
[1] => stdClass Object
(
[id] => 225
[user_id] => 1
[name] => Blue Quilted Leather Jacket by Minusey - $499
)
[2] => stdClass Object
(
[id] => 222
[user_id] => 1
[name] => Darling New Bathtub by Duravit - $6300
)
)
[1] => Array
(
[0] => stdClass Object
(
[id] => 226
[user_id] => 1
[name] => Eden Corner Tub by Glass - $2099
)
[1] => stdClass Object
(
[id] => 229
[user_id] => 1
[name] => Batman Tumbler Golf Cart - $50000
)
[2] => stdClass Object
(
[id] => 228
[user_id] => 1
[name] => Swirlio Frozen Fruit Dessert Maker - $60
)
) )
I have an array of products that I need to make sure are unique.
Need to make this array unique by id. These array are generated by pushing value.
I'm trying to solve this for more than a week now, but I dont get it to work. I know it should be easy...but anyway - I don't get it :D

Try this:
$array = array(
0 => array(
"name" => "test",
"id" => 4
),
1 => array(
"name" => "test2",
"id" => 152
),
2 => array(
"name" => "test2",
"id" => 152
)
);
$newArray = array();
foreach($array as $value) {
$newArray[$value['id']]['name'] = $value['name'];
$newArray[$value['id']]['id'] = $value['id'];
}

foreach($array as $key=>$inner_array)
{
foreach($array as $key_again=>$array_again)
{
if($key != $key_again)
{
if($inner_array['name'] != $array_again['name'] AND $inner_array['id'] != $array_again['id'])
{
//its okay
}
else
{
unset($array[$key]);
}
}
}
}

Not sure how the arrays are generated, but, if you can change that, you could set the array keys to the IDs directly and check if the id is already set.
Otherwise, you can do the following:
$unique = array();
foreach( $array as $values ) {
if( ! isset( $unique[$values['id']] ) ) {
$unique[$values['id']] = $values;
}
}

This will make your array unique:
$array = array(
0 => array(
"name" => "test",
"id" => 4
),
1 => array(
"name" => "test2",
"id" => 152
),
2 => array(
"name" => "test2",
"id" => 152
) );
$result = array();
$index = array();
foreach($array as $i => $elem) {
if(!isset($index[$elem['id']])) {
$result[$i] = $elem;
$index[$elem['id']] = 1;
}
}
echo var_export($result);
Output:
array (
0 =>
array (
'name' => 'test',
'id' => 4,
),
1 =>
array (
'name' => 'test2',
'id' => 152,
),
)

This will work. It could be considered more clean than a for loop, but I'm not sure about performance.
$array = [
[ "name" => "test", "id" => 4 ],
[ "name" => "test2", "id" => 152 ],
[ "name" => "test2", "id" => 152 ]
];
array_walk($array, function(&$item, $idx) use($array){
$matches = array_slice(array_keys($array, $item), 1);
if (in_array($idx, $matches)) {
$item = false;
}
});
$array = array_filter($array);
Edit Since you updated the data set to work with, you would need to flatten it 1 level:
$array = call_user_func_array('array_merge', $array);

Related

PHP : Add lowest value from duplicate records of array

I want to remove duplicate record which is highest value in array.
Array :
Array
(
[0] => Array
(
[id] => 1
[number] => 123
[price] => 6
)
[1] => Array
(
[id] => 2
[number] => 456
[price] => 6
)
[2] => Array
(
[id] => 3
[number] => 123
[price] => 5
)
)
Expected Result :
Array
(
[0] => Array
(
[id] => 2
[number] => 456
[price] => 6
)
[1] => Array
(
[id] => 3
[number] => 123
[price] => 5
)
)
number is duplicate field and after that need to compare price. Which will be lower that will be display. Rest of all should be removed.
What I tried :
$lowest = min($myArray);
$result = array_filter($myArray, function($value, $key) use ($lowest) {
return $value === $lowest;
}, ARRAY_FILTER_USE_BOTH);
How can i do that?
UPDATE :
#Daniel Dez solution is almost working. I used 3rd solution of him. But, It should be working like this.
For ex : number 123 is duplicate records now it's lowest price is 2. Then, it should be display rest of 123 number's array element remove.
Array :
$data = [
[
"id" => 1,
"number" => 123,
"price" => 2,
],
[
"id" => 2,
"number" => 456,
"price" => 6,
],
[
"id" => 3,
"number" => 123,
"price" => 5,
],
[
"id" => 4,
"number" => 123,
"price" => 11,
],
[
"id" => 5,
"number" => 456,
"price" => 5,
],
[
"id" => 6,
"number" => 123,
"price" => 5,
]
];
Expected Output :
Array
(
[0] => Array
(
[id] => 1
[number] => 123
[price] => 2
)
[1] => Array
(
[id] => 2
[number] => 456
[price] => 5
)
)
please help me.
Thanks.
Data:
$numbers = array_unique(array_column($data, 'number'));
usort($data, function ($a, $b) {
return $a['price'] - $b['price'];
});
$result = [];
foreach ($numbers as $number) {
foreach ($data as $item) {
if ($item['number'] == $number) {
break;
}
}
$result[] = $item;
}
print_r($result);

How to remove key of object array in php

I have a $variable with an array like this, is there a way to remove the key "attributes" and make it a simple array?
Array
(
[0] => stdClass Object
(
[attributes] => stdClass Object
(
[FID] => 11
[Kode_Provi] => 31
[Provinsi] => DKI Jakarta
[Kasus_Posi] => 808
[Kasus_Semb] => 50
[Kasus_Meni] => 85
)
)
[1] => stdClass Object
(
[attributes] => stdClass Object
(
[FID] => 12
[Kode_Provi] => 32
[Provinsi] => Jawa Barat
[Kasus_Posi] => 220
[Kasus_Semb] => 11
[Kasus_Meni] => 21
)
)
[2] => stdClass Object
(
[attributes] => stdClass Object
(
[FID] => 16
[Kode_Provi] => 36
[Provinsi] => Banten
[Kasus_Posi] => 152
[Kasus_Semb] => 7
[Kasus_Meni] => 14
)
)
)
``` .
Yes and no. You have an array of objects with properties there. You can not simply remove the "attributes key" because it actually represents a property of the object that is the value of the array at this point.
However, for the yes part, you can of course create an array out of your data structure and do not have objects on the levels anymore:
// Example of input from the question
$innerValue = new stdClass();
$innerValue->FID = 12;
$innerValue->Kode_Provi = 32;
$obj = new stdClass();
$obj->attributes = $innerValue;
$arr = [$obj];
// transforming it to array
$newArr = [];
foreach ($arr as $obj) {
$innerArr = [];
foreach ($obj->attributes as $prop => $value) {
$innerArr[$prop] = $value;
}
$newArr[] = $innerArr;
}
var_dump($newArr);
output looks like this:
array(1) {
[0] =>
array(2) {
'FID' =>
int(12)
'Kode_Provi' =>
int(32)
}
}
If you would like to just remove 'attributes' key it's just simple:
<?php
$variable = [
(object) [
'attributes' => (object) [
'FID' => 11,
'Kode_Provi' => 31,
'Provinsi' => 'DKI Jakarta',
'Kasus_Posi' => 808,
'Kasus_Semb' => 50,
'Kasus_Meni' => 85,
]
],
(object) [
'attributes' => (object) [
'FID' => 12,
'Kode_Provi' => 32,
'Provinsi' => 'Jawa Barat',
'Kasus_Posi' => 220,
'Kasus_Semb' => 11,
'Kasus_Meni' => 21,
]
]
];
$variable = array_map(
function($item) {
return $item->attributes;
},
$variable
);
print_r($variable);

In php is there a function like array_column for multidimensional arrays [duplicate]

This question already has answers here:
How to group subarrays by a column value?
(20 answers)
Closed 2 years ago.
Is there function that works similar to array_column for multidimensional arrays? Is there a function that translates the first array below to the second:
Array
(
[0] => Array
(
[foodType] => fruits
[itemID] => 1
[itemName] => apple
)
[1] => Array
(
[foodType] => fruits
[itemID] => 2
[itemName] => banana
)
[2] => Array
(
[foodType] => veggies
[itemID] => 3
[itemName] => carrot
)
[3] => Array
(
[foodType] => veggies
[itemID] => 4
[itemName] => broccoli
)
)
Resulting array:
Array
(
[fruits] => Array
(
[0] => Array
(
[itemID] => 1
[itemName] => apple
)
[1] => Array
(
[itemID] => 2
[itemName] => banana
)
)
[veggies] => Array
(
[0] => Array
(
[itemID] => 3
[itemName] => carrot
)
[1] => Array
(
[itemID] => 4
[itemName] => broccoli
)
)
)
No, there is not a function to get your expected output natively, though you can make your own functions, just use array_column to get the types/column, and then loop over your array, on match remove the item as to not duplicate iterations.
Something like:
<?php
$data = [
['foodType' => 'fruits', 'itemID' => 1, 'itemName' => 'apple'],
['foodType' => 'fruits', 'itemID' => 2, 'itemName' => 'banana'],
['foodType' => 'veggies', 'itemID' => 3, 'itemName' => 'carrot'],
['foodType' => 'veggies', 'itemID' => 4, 'itemName' => 'broccoli']
];
function array_column_multi ($array, $column) {
$types = array_unique(array_column($array, $column));
$return = [];
foreach ($types as $type) {
foreach ($array as $key => $value) {
if ($type === $value[$column]) {
unset($value[$column]);
$return[$type][] = $value;
unset($array[$key]);
}
}
}
return $return;
}
print_r(array_column_multi($data, 'foodType'));
https://3v4l.org/KQVeN
Result:
Array
(
[fruits] => Array
(
[0] => Array
(
[itemID] => 1
[itemName] => apple
)
[1] => Array
(
[itemID] => 2
[itemName] => banana
)
)
[veggies] => Array
(
[0] => Array
(
[itemID] => 3
[itemName] => carrot
)
[1] => Array
(
[itemID] => 4
[itemName] => broccoli
)
)
)
Oh I just noticed that you're aggregating them by ID. There's not a function for that, you're going to need to iterate over the input with a loop, and populate an output array with the data you want. Eg:
$output = [];
foreach($input_array as $item) {
$output[$item['id']][] = [
'itemID' => $item['itemID'],
'itemName' => $item['itemName']
];
}
Quite old question, but I hope it help someone. Unfortunately there's no native function yet but output is achievable using php's array_filter():
$foods = [
[
'foodType' => 'fruits',
'itemID' => 1,
'itemName' => 'apple',
],
[
'foodType' => 'fruits',
'itemID' => 2,
'itemName' => 'banana',
],
[
'foodType' => 'veggies',
'itemID' => 3,
'itemName' => 'carrot',
],
[
'foodType' => 'veggies',
'itemID' => 4,
'itemName' => 'broccoli',
]
];
$grouped_foods = [];
$groupByColumn = 'foodType';
array_filter($foods, function ($foodItem) use(&$grouped_foods, $groupByColumn) {
$grouped_foods[$foodItem[$groupByColumn]][] = array_filter($foodItem, function ($key) use($groupByColumn) {
return $key != $groupByColumn;
}, ARRAY_FILTER_USE_KEY);
});
echo "<pre>";
print_R($grouped_foods);
echo "</pre>";
see in action: https://3v4l.org/bbX5A
Disclaimer: for/foreach loops are significantly faster in performance than native array functions.
I prefer using the following solution.
Example
"allergens" => array:5 [
0 => array:2 [
"id" => "10"
"object" => array:1 [
"allergens" => "10"
]
]
1 => array:2 [
"id" => "11"
"object" => array:1 [
"allergens" => "11"
]
]
2 => array:2 [
"id" => "4"
"object" => array:1 [
"allergens" => "4"
]
]
]
Giving this example, if you would like an array containing only the value of allergens then use the following code.
Solution
$allergens = array_map( function ( $ar ) {
return $ar['allergens'];
}, array_column( $allergensArr, 'object' ) );
Result
array:5 [
0 => "10"
1 => "11"
2 => "4"
]

how to get row index from mysql result in codeignitier when search by id or code

I have the data :
Array
(
[0] => Array
(
[id] => 12
[code] => 12345
[name] => Aaron
)
[1] => Array
(
[id] => 5
[code] => 16784
[name] => Bryan
)
[2] => Array
(
[id] => 35
[code] => 32467
[name] => Charlie
)
[3] => Array
(
[id] => 25
[code] => 44513
[name] => Denise
)
[4] => Array
(
[id] => 44
[code] => 15774
[name] => Michael
)
)
In my model i create function :
private function getPosition($field_search, $field_value){ // ID or code
$this->db->select('*');
$this->db->from($this->table);
$this->db->order_by('name','asc');
$result = $this->db->get()->result();
$pos = array_search($field_value, array_column($result, $field_search));
return ($pos !==false ? $pos : -1);
}
if i want to get row index of "32467", i just call
$pos = $this->getPosition('code', '32467');
then i got the row index is "2",
but i wonder, how to get row index if the query is :
$this->db->select('*');
$this->db->from($this->table);
$this->db->where('code', '32467');
$this->db->order_by('name','asc');
$result = $this->db->get()->result();
litte correction in my question,
i mean, if we index in database where code = "32467", we've got index is "2", how to get return if index is "2"
thanks for your help...
<?php
$userdb= Array
(
"0" => Array(
'id' => "12",
'code' => "12345",
'name' => 'Aaron'
),
"1" => Array
(
"id" => "5",
"code" => "16784",
"name" => "Bryan"
),
"2" => Array
(
"id" => "35",
"code" => "32467",
"name" => "Charlie"
),
"3" => Array
(
"id" => "25",
"code" => "44513",
"name" => "Denise"
),
"4" => Array
(
"id" => "44",
"code" => "15774",
"name" => "Michael"
),
);
$key = array_search(32467, array_column($userdb, 'code'));
echo ("The key is: ".$key);
private function getPosition($field_search, $field_value){ // ID or code
$this->db->select('*');
$this->db->from($this->table);
$this->db->order_by('name','asc');
$result = $this->db->get()->result();
$key = array_search($field_value, array_column($result, $field_search));
return $key;
}
?>

How to loop through a multi-layer array and replace some associate values in it?

How can I loop through a multi-layer array and replace some associate values in it?
For instance, this is my array,
$items = array(
0 => array(
"id" => "1",
"title" => "parent 1",
"children" => array()
),
1 => array(
"id" => "2",
"title" => "parent 2",
"children" => array (
0 => array(
"id" => "4",
"title" => "children 1",
"granchildren" => array(
0 => array(
"id" => "7",
"title" => "granchildren 1"
),
1 => array(
"id" => "8",
"title" => "granchildren 2"
)
)
),
1 => array(
"id" => "5",
"title" => "children 2",
"granchildren" => array()
)
),
),
3 => array(
"id" => "3",
"title" => "parent 3",
"children" => array()
)
);
These are two working functions I have,
function translate ($id){
$items = array(
0 => array(
"id" => 1,
"title" => "parent 1 en"
),
1 => array(
"id" => 4,
"title" => "children 1 en"
),
2 => array(
"id" => 8,
"title" => "granchildren 2 en"
)
);
foreach($items as $item) {
if($id === $item['id'])
{
return $item['title'];
}
}
}
function looper ($items){
$new_items = array();
foreach($items as $key => $item) {
if(isset($key) && is_array($key)){
$new_items[$key] = translate($item['id']);
}else {
//looper($item);
}
}
return $new_items;
}
print_r(looper ($items));
This is the result I am after,
Array
(
[0] => Array
(
[id] => 1
[title] => parent 1 en // translated
[children] => Array
(
)
)
[1] => Array
(
[id] => 2
[title] => parent 2
[children] => Array
(
[0] => Array
(
[id] => 4
[title] => children 1 en // translated
[granchildren] => Array
(
[0] => Array
(
[id] => 7
[title] => granchildren 1
)
[1] => Array
(
[id] => 8
[title] => granchildren 2 en // translated
)
)
)
[1] => Array
(
[id] => 5
[title] => children 2
[granchildren] => Array
(
)
)
)
)
[3] => Array
(
[id] => 3
[title] => parent 3
[children] => Array
(
)
)
)
Is it possible?
Sounds like a job for array_walk or array_walk_recursive.
It will call a user-supplied function for every item in an array. You can have it modify the array by reference to achieve what you're after.

Categories