How check array element exist in two-dimessional array in php [duplicate] - php

This question already has answers here:
How to search by key=>value in a multidimensional array in PHP
(17 answers)
Closed 9 years ago.
I have an array that is like:
Array
(
[0] => Array
(
[product_id] => 1
[product_name] => T-Shirts
[quantity] => 2
[price] => 300
)
[1] => Array
(
[product_id] => 2
[product_name] => Red Shirt
[quantity] => 4
[price] => 200
)
[2] => Array
(
[product_id] => 3
[product_name] => Cap
[quantity] => 2
[price] => 50
)
)
I want to check whether the product_id exist or not. I tried to in_array but did not get any result.
Is there any built-in function to check it without putting the array in loop.

As mentioned by gloomy.penguin, you could use array_filter
<?php
$a = Array
(
0 => Array
(
"product_id" => 1,
"product_name" => "T-Shirts",
"quantity" => 2,
"price" => 300,
),
1 => Array
(
"product_id" => 2,
"product_name" => "Red Shirt",
"quantity" => 4,
"price" => 200,
),
2 => Array
(
"product_id" => 3,
"product_name" => "Cap",
"quantity" => 2,
"price" => 50,
),
);
$result = array_filter($a, function($var) {
if ($var['product_id'] == 3) return true;
});
if (empty($result)) echo "Not found";
else echo "Found";
echo var_dump($result);
?>

You can loop through every product:
foreach($array as $product) {
if(isset($product['product_id']))
// do something
}
I don't think there's a built-in function to handle this.

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);

Displaying HTML table from PHP array with two headers

I have an array containing sport results that looks like this:
Array
(
[0] => Array
(
[name] => Alexander
[distance] => 60
[value] => 9
)
[1] => Array
(
[name] => Alexander
[distance] => 100
[value] => 10
)
[2] => Array
(
[name] => Alexander
[distance] => 200
[value] => 11
)
[3] => Array
(
[name] => Alexander
[distance] => 400
[value] => 12
)
[4] => Array
(
[name] => Dmitriy
[distance] => 60
[value] => 5
)
[5] => Array
(
[name] => Dmitriy
[distance] => 100
[value] => 6
)
[6] => Array
(
[name] => Dmitriy
[distance] => 200
[value] => 7
)
[7] => Array
(
[name] => Dmitriy
[distance] => 400
[value] => 8
)
[8] => Array
(
[name] => Sergei
[distance] => 60
[value] => 1
)
[9] => Array
(
[name] => Sergei
[distance] => 100
[value] => 2
)
[10] => Array
(
[name] => Sergei
[distance] => 200
[value] => 3
)
[11] => Array
(
[name] => Sergei
[distance] => 400
[value] => 4
)
)
I need to display the array data in a specific way in a html table, that should look like this. Top header should contain all unique values from "distance" key and left header should contain all unique values from "name" key:
| 60 | 100 | 200 | 400
===========================================
Alexnader | 9 | 10 | 11 | 12
===========================================
Dmitriy | 5 | 6 | 7 | 8
===========================================
Sergei | 1 | 2 | 3 | 4
How can I do it the fastest way, with the least number of loops or using php array methods? Thank you.
Get unique distances and names for the table.
$names = array_unique(array_map(fn($a) => $a['name'], $data));
$dists = array_unique(array_map(fn($a) => $a['distance'], $data));
Make a function to find by name and distance for table values.
function findValue($dist, $name, $data): string {
foreach($data as $d) {
if($d['name'] != $name || $d['distance'] != $dist ) continue;
return (string) $d['value'];
}
return '';
}
Now out output the table beginning with the head and distances
echo "<table>\n";
echo "<tr><th></th>", implode('', array_map(fn($col) => "<th>$col</th>", $dists)), "</tr>\n";
Put out the data by row for each name using our find function
foreach($names as $name) {
$row = [];
foreach($dists as $dist) {
$row[] = '<td>' . findValue($dist, $name, $data) . '</td>';
}
$rowText = join('', $row);
echo "<tr><td>$name</td>$rowText</tr>\n";
}
Finally close the table.
echo "</table>\n";
The result is
<table>
<tr><th></th><th>60</th><th>100</th><th>200</th><th>400</th></tr>
<tr><td>Alexander</td><td>9</td><td>10</td><td>11</td><td>12</td></tr>
<tr><td>Dmitriy</td><td>5</td><td>6</td><td>7</td><td>8</td></tr>
<tr><td>Sergei</td><td>1</td><td>2</td><td>3</td><td>4</td></tr>
</table>
We have to restructure the array first
$array = Array
(
"0" => Array
(
"name" => "Alexander",
"distance" => 60,
"value" => 9
),
"1" => Array
(
"name" => "Alexander",
"distance" => 100,
"value" => 10
),
"2" => Array
(
"name" => "Alexander",
"distance" => 200,
"value" => 11
),
"3" => Array
(
"name" => "Alexander",
"distance" => 400,
"value" => 12
),
"4" => Array
(
"name" => "Dmitriy",
"distance" => 60,
"value" => 5
),
"5" => Array
(
"name" => "Dmitriy",
"distance" => 100,
"value" => 6
),
"6" => Array
(
"name" => "Dmitriy",
"distance" => 200,
"value" => 7
),
"7" => Array
(
"name" => "Dmitriy",
"distance" => 400,
"value" => 8
),
"8" => Array
(
"name" => "Sergei",
"distance" => 60,
"value" => 1
),
"9" => Array
(
"name" => "Sergei",
"distance" => 100,
"value" => 2
),
"10" => Array
(
"name" => "Sergei",
"distance" => 200,
"value" => 3
),
"11" => Array
(
"name" => "Sergei",
"distance" => 400,
"value" => 4
)
);
$table_heading = array_unique(array_column($array, "distance"));
$restructured_array = [];
foreach($array as $row){
if(!isset($restructured_array[$row["name"]])){
$restructured_array[$row["name"]] = [];
}
$restructured_array[$row["name"]][$row["distance"]] = $row["value"];
}
Now the array can be looped to print the table.
echo "<table><thead><tr>";
echo "<th></th>";
foreach($table_heading as $heading){
echo "<th>".$heading."</th>";
}
echo "</tr></thead>";
echo "<tbody>";
foreach ($restructured_array as $key=>$rows){
echo "<tr><th>".$key."</th>";
foreach ($rows as $k=>$row){
echo "<td>".$row."</td>";
}
}
echo "</tbody></table>";
The output will be
60 100 200 400
Alexander 9 10 11 12
Dmitriy 5 6 7 8
Sergei 1 2 3 4

How to Remove value from an array using another array with multiple values?

I have two array Array1 and Array2 and I need to remove Array2 value from Array1 I show my both the Array here.
In Array1 I have utype_id is 11 and 14 and I need to remove this id record from Array2 so how can I do it can you please help me?
Array1(
[0] => stdClass Object
(
[id] => 22
[accessid] => 2
[utype_id] => 11
[discount] => 3434
[published] => 1
)
[1] => stdClass Object
(
[id] => 23
[accessid] => 2
[utype_id] => 14
[discount] => 2
[published] => 1
)
)
Array2
(
[0] => stdClass Object
(
[id] => 9
[type_name] => Admin
[description] => admin
[published] => 0
)
[1] => stdClass Object
(
[id] => 10
[type_name] => Senior sales
[description] => senior sales
[published] => 0
)
[2] => stdClass Object
(
[id] => 11
[type_name] => junior sales
[description] => junior
[published] => 1
)
[3] => stdClass Object
(
[id] => 14
[type_name] => dealer
[description] => dealer
[published] => 0
)
[4] => stdClass Object
(
[id] => 15
[type_name] => fgdg
[description] => dfg
[published] => 1
)
[5] => stdClass Object
(
[id] => 16
[type_name] => fgdfg
[description] => fgdfg
[published] => 0
)
)
I didn't get any solution for this. I need only 9,10,15,16 Record id from Array2.
Just for entertainment purposes (and I was feeling a bit left out :( ). Index both arrays by the ID (need php 7+ for array_column() to support objects as input) and then array_diff_key() to remove any from the second array...
print_r(array_diff_key(array_column($array2, null, "id"),
array_column($array1, null, "utype_id")));
I would like to say that a foreach() solution is faster than this, just wanted to join in and post some original content.
First, extract utype_ids from first array, make them keys to speed up search:
$utype_ids = [];
foreach ($array1 as $item) {
$utype_ids[$item->utype_id] = 1;
}
Then, filter second array using $utype_ids:
$filtered_array = array_filter(
$array2,
function($v) use ($utype_ids) {
return !isset($utype_ids[$v->id]);
}
);
Demo: https://3v4l.org/i2heV
Use nested loops to perform the qualifying checks. Use a break as a matter of best practice to avoid unnecessary iterations.
Code: (Demo)
$blacklist = [
(object)["id" => 22,"accessid" => 2, "utype_id" => 11, "discount" => 3434, "published" => 1],
(object)["id" => 23,"accessid" => 2, "utype_id" => 14, "discount" => 2, "published" => 1]
];
$rows = [
(object)["id" => 9, "type_name" => "Admin", "description" => "admin", "published" => 0],
(object)["id" => 10, "type_name" => "Senior sales", "description" => "senior sales", "published" => 0],
(object)["id" => 11, "type_name" => "junior sales", "description" => "junior sales", "published" => 1],
(object)["id" => 14, "type_name" => "dealer", "description" => "dealer", "published" => 0],
(object)["id" => 15, "type_name" => "fgdg", "description" => "dfg", "published" => 1],
(object)["id" => 16, "type_name" => "fgdfg", "description" => "fgdfg", "published" => 0]
];
foreach ($blacklist as $disqualifier) { // iterate the blacklist
foreach ($rows as $index => $row) { // iterate the list to be checked
if ($row->id === $disqualifier->utype_id) { // if row should be disqualified
unset($rows[$index]); // remove the row
break; // stop checking the $rows for this $disqualifier
}
}
}
var_export($rows);
...if you need the output to be reindexed, you can call array_values($rows).
If these arrays of objects are coming from a database table, you should be improving your query to do this filtration process in advance.
You can use..
$arr1ids = array();
foreach($array1 as $val1){
$arr1ids[] = $val1->utype_id;
}
$resArr = array();
foreach($array2 as $val2){
if(!in_array($val2->utype_id,$arr1ids)){
$resArr[] = $val2;
}
}
print_r($resArr);

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"
]

Filter php array based on other array with different elements [duplicate]

This question already has answers here:
While comparing associative rows between two 2d arrays, array_diff_assoc() gives the wrong difference
(3 answers)
Closed 4 months ago.
I have an array $items as such:
[0] => Array (
[itemid] => 8
[name] => A
[rating] => 9.5
)
[1] => Array (
[itemid] => 41
[name] => B
[rating] => 9.5
)
and another array $array as such:
[0] => Array (
[itemid] => 458
[name] => C
[rating] => 9.603
)
[1] => Array (
[itemid] => 460
[name] => D
[rating] => 9.603
)
[2] => Array (
[itemid] => 8
[name] => A
[rating] => 9.523
)
[3] => Array (
[itemid] => 41
[name] => B
[rating] => 9.2
)
What I would like to do is return the array $array, but with all the elements from $items filtered out. In this case it would return $array, but without [2] and [3].
I've tried with array_diff(), but the rating can change from one array to the other, so the elements in the one array are not always the same as in the other array.
How do I go about this?
Is this what you're looking for?
<?php
$arr1 = [];
$arr1[] = [ "itemid" => 8, "name" => "A", "rating" => 9.5 ];
$arr1[] = [ "itemid" => 41, "name" => "B", "rating" => 9.5 ];
$arr2 = [];
$arr2[] = [ "itemid" => 458, "name" => "C", "rating" => 9.603 ];
$arr2[] = [ "itemid" => 460, "name" => "D", "rating" => 9.603 ];
$arr2[] = [ "itemid" => 8, "name" => "A", "rating" => 9.523 ];
$arr2[] = [ "itemid" => 41, "name" => "B", "rating" => 9.2 ];
function compare_by_itemid($a, $b) {
return $a['itemid'] - $b['itemid'];
}
var_dump(array_udiff($arr2,$arr1,'compare_by_itemid'));
You could first get the item ID values as keys of an $exclude associative array (like a set), and then iterate $array to perform the filter:
$exclude = array_column($items, "itemid", "itemid"); // create set
foreach($array as $row) {
if (!isset($exclude[$row["itemid"]])) $result[] = $row;
}
The $result will have entries with item IDs that do not occur in $items.

Categories