Finding value from another one in an array of arrays - php

I got the follwing array and I would like to retrieve the name by the id:
Array
(
[0] => Array
(
[id] => 1
[name] => john
)
[1] => Array
(
[id] => 2
[name] => mark
)
etc...
It is doable with double foreach loop and a conditional test, but is there a more elegant way?

Assuming that id is unique...
Long Version
$arr = [
['id'=1, 'name'='john'],
['id'=2, 'name'='mark'],
];
$lookup = [];
foreach($arr as $row) {
$id = $row['id'];
$name = $row['name'];
$lookup[$id] = $name;
}
// find name for id, 2
echo $lookup[2];
// ==> mark
Short Version
...see Progrock’s solution!

You can use array_column to map ids to names:
<?php
$arr = [
['id' => 1, 'name' => 'Rolf'],
['id' => 3, 'name' => 'Gary'],
['id' => 2, 'name' => 'Jimmy'],
];
$id_names = array_column($arr, 'name', 'id');
var_export($id_names);
print $id_names[3];
Output:
array (
1 => 'Rolf',
3 => 'Gary',
2 => 'Jimmy',
)Gary

Related

How to merge two arrays diferents on one

How to update an array of objects, adding the quantities if you already have the same ID, or if you have not created a new object.
I tried to explain in the code with the arrays and also with the idea of how I would like the result to be.
old Array
$a1 = [
array(
"id" => 1,
"qty" => 1
),
array(
"id" => 2,
"qty" => 1
)
];
$a2 = [
array(
"id" => 1,
"qty" => 1
)
];
$output = array_merge($a1, $a2);
echo '<pre>';
print_r($output);
echo '</pre>';
Result Error:
Array
(
[0] => Array
(
[id] => 1
[qty] => 1
)
[1] => Array
(
[id] => 2
[qty] => 1
)
[2] => Array
(
[id] => 1
[qty] => 1
)
)
What I need, in addition to if the ID does not contain, add.
Array
(
[0] => Array
(
[id] => 1
[qty] => 2
)
[1] => Array
(
[id] => 2
[qty] => 1
)
)
You can take the first array as base, then search for the key (if existing) where the product matches the id. Then either add the quantity and recalculate the price or you just add the reformatted element (id to product conversion).
$result = $a;
foreach($b as $element) {
$matchingProductIndex = array_search($element['id'], array_column($a, 'product'));
if ($matchingProductIndex !== false) {
$pricePerUnit = $result[$matchingProductIndex]['price'] / $result[$matchingProductIndex]['qty'];
$result[$matchingProductIndex]['qty'] += $element['qty'];
$result[$matchingProductIndex]['price'] = $result[$matchingProductIndex]['qty'] * $pricePerUnit;
} else {
$result[] = [
'qty' => $element['qty'],
'product' => $element['id'],
'price' => $element['price'],
];
}
}
print_r($result);
Working example.
Loop through both arrays with foreach and check the ids against each other.
https://paiza.io/projects/lnnl5HeJSFIOz_6KD6HRIw
<?php
$arr1 = [['qty' => 4, 'id' => 4],['qty' => 1,'id' => 30]];
$arr2 = [['id' => 30, 'qty' => 19],['id' => 31, 'qty' => 2]];
$arr3 = [];
foreach($arr1 as $iArr1){
$match = false;
foreach($arr2 as $iArr2){
if($iArr1['id'] === $iArr2['id']){
$arr3[] = ['id' => $iArr1['id'], 'qty' => $iArr1['qty'] + $iArr2['qty']];
$match = true;
}
}
if(!$match){
$arr3[] = $iArr1;
$arr3[] = $iArr2;
}
}
print_r($arr3);
?>
One approach could be one I more often suggested.
First lets merge $a2 with one to simplify looping over one larger collection.
If we then create a small mapping from id to its index in the result array we can update the running total of qty.
$map = [];
$result = [];
// Merge the two and do as per usual, create a mapping
// from id to index and update the qty at the corresponding index.
foreach (array_merge($a1, $a2) as $subarr) {
$id = $subarr['id'];
if (!key_exists($id, $map)) {
$index = array_push($result, $subarr) - 1;
$map[$id] = $index;
continue;
}
$result[$map[$id]]['qty'] += $subarr['qty'];
}
echo '<pre>', print_r($result, true), '</pre>';
Output:
Array
(
[0] => Array
(
[id] => 1
[qty] => 2
)
[1] => Array
(
[id] => 2
[qty] => 1
)
)

How to filter an associative array?

I have to deal with a refactoring, to reduce the number of lines of code in PHP, to filter an associative array.
So I'm making a select from DB in MySQL, to get an associative array. So my "Object" has a category and a surname field.
while ($row = mysqli_fetch_array($result)) {
$array[] = $row['category'];
$array[] = $row['Surname'];
}
I want to obtain from this array, as many other sub-array, splitted by the category. I mean the category Array identification may be:
$categories = array("A","B","C","D");
So what I want, is to obtain one Array for each Category, which contains all the Surname, of that category.
So suppose that the method works, something like that:
$arrayFiltered = method_filter($array_asso,"A");
At the end I want something like that:
foreach ($categories as &$value) {
$arrayFiltered = method_filter($array_asso,$value);
my_method_which_needs_the_filtered_array($arrayFiltered);
}
Thank you in advance for your help.
As far as i get you - you need one array which will contain all the surname category wise so that you can access them easily. This should help -
while ($row = mysqli_fetch_array($result)) {
$categories[$row['category']][] = $row['Surname'];
}
Simply store the category as key and all the surname as values to that key.
Sergeant's approach is the easiest. Just for the sake of it, here is an approach with array_filter() (just in case you have to have an unfiltered array as well):
$array = [];
$categories = array("A","B","C","D");
while ($row = mysqli_fetch_array($result)) {
$item = [
'category' => $row['category'],
'surname' => $row['Surname']
];
$array[] = $item;
}
$categorized = [];
foreach ($categories as $category) {
$categorized[$category] = array_filter($array, function($item) use ($category) {
return $item['category'] == $category;
});
}
Here is a proof of concept without the need of a database connection:
$categories = array("A","B","C","D");
$array = [
['category' => 'A', 'Surname' => 'A Name 1'],
['category' => 'A', 'Surname' => 'A Name 2'],
['category' => 'B', 'Surname' => 'B Name 1'],
['category' => 'B', 'Surname' => 'B Name 2'],
['category' => 'B', 'Surname' => 'B Name 3'],
['category' => 'C', 'Surname' => 'C Name'],
];
$categorized = [];
foreach ($categories as $category) {
$categorized[$category] = array_filter($array, function($item) use ($category) {
return $item['category'] == $category;
});
}
print_r($categorized);
Output:
Array
(
[A] => Array
(
[0] => Array
(
[category] => A
[Surname] => A Name 1
)
[1] => Array
(
[category] => A
[Surname] => A Name 2
)
)
[B] => Array
(
[2] => Array
(
[category] => B
[Surname] => B Name 1
)
[3] => Array
(
[category] => B
[Surname] => B Name 2
)
[4] => Array
(
[category] => B
[Surname] => B Name 3
)
)
[C] => Array
(
[5] => Array
(
[category] => C
[Surname] => C Name
)
)
[D] => Array
(
)
)

array's key match with another array php

Ex :
First array:
Array
(
[0] => id
[1] => ADDRESS
[2] => ADDRESS1
[3] => name
)
Second array:
Array
(
[id] => 1
[name] => Ankit
[city] => SURAT
)
Required OUTPUT :
[id] => 1
[ADDRESS]=>
[ADDRESS1]=>
[name] => Ankit
here we can see that value of first array ADDRESS,ADDRESS1 doesn't exist in array 2 key,
so i need value to be set null for ADDRESS,ADDRESS1 and unnecessary field of array 2 is city which key doesn't exist in first array values is need to be unset from result array
CODE :
$field_arr= array('0'=>"id",
"1"=>"ADDRESS",
"2"=>"ADDRESS1",
'3'=>"name",
);
$arr=array("id"=>"1",
'name'=>"Ankit",
"city"=>"Ahmedabad");
$matching_fields =(array_diff_key(array_flip($field_arr),(array_intersect_key($arr,array_flip($field_arr)))));
if(!empty($matching_fields)){
foreach($matching_fields as $key=>$value){
$new_arr[$key]=null;
}
}
print_r($new_arr);
exit;
CURRENT OUTPUT OF NEW ARRAY :
Array
(
[ADDRESS] =>
[ADDRESS1] =>
)
but this is long process.as well as performance also matter. i want whole code reconstruct which i have made and just get output which is required output
Here some more need help need i want same sequence of key of output array same as first array value
my required output :
[id] => 1
[ADDRESS]=>
[ADDRESS1]=>
[name] => Ankit
current output :
[id] => 1
[name] => Ankit
[ADDRESS]=>
[ADDRESS1]=>
Thanks in advance
Just try with:
$keys = array('id', 'name', 'ADDRESS', 'ADDRESS1');
$data = array(
'id' => 1,
'name' => 'Ankit',
'city' => 'SURAT',
);
$output = $data + array_fill_keys($keys, null);
Output:
array (size=5)
'id' => int 1
'name' => string 'Ankit' (length=5)
'city' => string 'SURAT' (length=5)
'ADDRESS' => null
'ADDRESS1' => null
$keys = array_unique(array_merge($field_arr, array_keys($arr)));
$new_array = array();
foreach ($keys as $key)
{
$new_array[$key] = isset($arr[$key]) ? $arr[$key] : '';
}
echo "<pre>";
print_r($new_array);
You can use following;
$first = array(
"id",
"name",
"ADDRESS",
"ADDRESS1"
);
$second = array(
"id" => "1",
"name" => "Ankit",
"city" => "SURAT"
);
foreach ($first as $key) {
if ($second[$key] == null) {
$second[$key] = null;
}
}
var_dump($second);
Here is working demo: Demo

How to add new index and value from another array in PHP?

I need your help with my problem. My problem is I have 2 arrays the first one is the main array. The second is the array for my new data.
Let's say I have these arrays.
This is the main array:
Array
(
0 => Array
(
'id' => 1,
'name' => 'Apple',
'age' => 12
)
1 => Array
(
'id' => 2,
'name' => May,
'age' => 13
)
)
This is the second array:
Array
(
1 => Array
(
'gender' => 'Male'
)
2 => Array
(
'gender' => 'Female'
)
)
And I have this loop in PHP
foreach($main_array as &$main){
//this is the loop inside the first array
// how can I add the second array with it?
}
This is the sample output:
[0] => Array
(
[id] => 1
[name] => Apple
[age] => 12
[gender] => Female
)
[1] => Array
(
[id] => 2
[name] => May
[age] => 13
[gender] => Female
)
How can I do that? Any suggestions? That's all thanks.
for($i=0; $i<count($main_array); $i++){
for($j=0; $j<count($second_array); $j++){
if($main_array[$i]['id'] == $j){
$main_array[$i]['gender'] = $second_array[$j]['gender']
}
}
}
I fixed your example code, it wont run otherwise.
<?php
// Test data:
$main_array = Array(
0 => Array(
'id' => 1,
'name' => 'Apple',
'age' => 12
),
1 => Array (
'id' => 2,
'name' => 'May',
'age' => 13
)
);
$lookup = Array(
1 => Array(
'gender' => 'Male'
),
2 => Array(
'gender' => 'Female'
)
);
// Your answer:
foreach ($main_array as &$main) {
if (array_key_exists($main['id'],$lookup)) {
$main['gender'] = $lookup[$main['id']]['gender']; // <-- sets gender value
}
}
// Output it to browser:
echo '<pre>$main_array = '.print_r($main_array,true).'</pre>';
The array_key_exists() check is there to avoid errors such as PHP Notice: Undefined offset: 123 when the $lookup data is incomplete.
If you want to merge all of the data from both arrays:
PHP tools:
The exact behaviors of these functions needs to be studied and tested before usage, to make sure it fits your intent.
// array merge recursive doesn't merge numeric keys
$main_array = array_merge_recursive($main_array, $secondary_array);
// array replace recursive has a downside of replacing stuff
$main_array = array_replace_recursive($main_array, $secondary_array);
Rolling your own:
foreach($main_array as $i => &$main){
if(isset($secondary_array[$i])) {
foreach($secondary_array[$i] AS $key => $value) {
$main[$key] = $value;
}
}
}
Both of the above solutions only apply if the array-indexes of $main_array and $secondary_array match.
In your example your arrays don't match:
- $secondary_array[0] doesn't exist so $main_array[0] will not be populated with a 'gender' value;
- $main_array[2] doesn't exist so $main_array[2] will be created and it will only have a 'gender' value same as $secondary_array[2]['gender']
If you want to only merge some bits and pieces of the arrays:
Rolling your own:
foreach($main_array as $i => &$main) {
if(isset($secondary_array[$i])) and isset($secondary_array[$i]['gender'])) {
$main['gender'] = $secondary_array[$i]['gender'];
}
}
foreach($main_array as &$main){//this is the loop inside the first array
foreach($second_array as &$second){ //this is the loop inside the second array
}
}
foreach($arr1 as $k => $arr1Item) {
$arr1[$k]['gender'] = $arr2[$k]['gender'];
}

(PHP) Converting an array of arrays from one format into another

I currently have an array, created from a database, an example of which looks like the following:
Array(
[0] => Array (
objectid => 2,
name => title,
value => apple
),
[1] => Array (
objectid => 2,
name => colour,
value => red
),
[2] => Array (
objectid => 3,
name => title,
value => pear
),
[3] => Array (
objectid => 3,
name => colour,
value => green
)
)
What I would like to do is group all the items in the array by their objectid, and convert the 'name' values into keys and 'value' values into values of an associative array....like below:
Array (
[0] => Array (
objectid => 2,
title => apple,
colour => red
),
[1] => Array (
objectid => 3,
title => pear,
colour => green
)
)
I've tried a few things but haven't really got anywhere.. Any ideas?
Thanks in advance
This should work with your current setup and should be able to handle as many key-value pairs as available:
<?php
$results = array(
array('objectid' => 2, 'name' => 'title', 'value' => 'apple'),
array('objectid' => 2, 'name' => 'color', 'value' => 'red'),
array('objectid' => 3, 'name' => 'title', 'value' => 'pear'),
array('objectid' => 3, 'name' => 'color', 'value' => 'green'));
$final = array();
foreach ($results as $result) {
$final[$result['objectid']]['objectid'] = $result['objectid'];
$final[$result['objectid']][$result['name']] = $result['value'];
}
print_r($final);
It would be easier to have the array keys correspond with your object id, that way you can iterate through your existing array, and add the key-value pairs for each object, like so:
$newArray = array();
foreach ($results as $result) {
if (!array_key_exists($result['objectid'], $newArray)) {
$newArray[$result['objectid'] = array();
}
foreach ($result as $key => $value) {
$newArray[$result['objectid'][$key] = $value;
}
}
Peter's method is perfectly valid, I just thought I would show a shorter version of the same thing (couldn't do in a comment)
foreach( $array as $obj ) {
if( !isset( $objects[$obj['objectid']] ) )
$objects[$obj['objectid']]['objectid'] = $obj['objectid'];
$objects[$obj['objectid']][$obj['name']] = $obj['value'];
}

Categories