$array1 = array("$name1" => "$id1");
$array2 = array("$name2" => "$id2", "$name3" => "$id3");
I need a new array combining all together, i.e. it would be
$array3 = array("$name1" => "$id1", "$name2" => "$id2", "$name3" => "$id3");
What is the best way to do this?
Sorry, I forgot, the ids will never match each other, but technically the names could, yet would not be likely, and they all need to be listed in one array. I looked at array_merge but wasn't sure if that was best way to do this. Also, how would you unit test this?
array_merge() is more efficient but there are a couple of options:
$array1 = array("id1" => "value1");
$array2 = array("id2" => "value2", "id3" => "value3", "id4" => "value4");
$array3 = array_merge($array1, $array2/*, $arrayN, $arrayN*/);
$array4 = $array1 + $array2;
echo '<pre>';
var_dump($array3);
var_dump($array4);
echo '</pre>';
// Results:
array(4) {
["id1"]=>
string(6) "value1"
["id2"]=>
string(6) "value2"
["id3"]=>
string(6) "value3"
["id4"]=>
string(6) "value4"
}
array(4) {
["id1"]=>
string(6) "value1"
["id2"]=>
string(6) "value2"
["id3"]=>
string(6) "value3"
["id4"]=>
string(6) "value4"
}
Check out array_merge().
$array3 = array_merge($array1, $array2);
There is also array_replace, where an original array is modified by other arrays preserving the key => value association without creating duplicate keys.
Same keys on other arrays will cause values to overwrite the original array
New keys on other arrays will be created on the original array
I use a wrapper around array_merge to deal with SeanWM's comment about null arrays; I also sometimes want to get rid of duplicates. I'm also generally wanting to merge one array into another, as opposed to creating a new array. This ends up as:
/**
* Merge two arrays - but if one is blank or not an array, return the other.
* #param $a array First array, into which the second array will be merged
* #param $b array Second array, with the data to be merged
* #param $unique boolean If true, remove duplicate values before returning
*/
function arrayMerge(&$a, $b, $unique = false) {
if (empty($b)) {
return; // No changes to be made to $a
}
if (empty($a)) {
$a = $b;
return;
}
$a = array_merge($a, $b);
if ($unique) {
$a = array_unique($a);
}
}
$array = array(
22 => true,
25 => true,
34 => true,
35 => true,
);
print_r(
array_replace($array, [
22 => true,
42 => true,
])
);
print_r(
array_merge($array, [
22 => true,
42 => true,
])
);
If it is numeric but not sequential associative array, you need to use array_replace
UPDATE
Just a quick note, as I can see this looks really stupid, and it has no good use with pure PHP because the array_merge just works there. BUT try it with the PHP MongoDB driver before you rush to downvote. That dude WILL add indexes for whatever reason, and WILL ruin the merged object. With my naïve little function, the merge comes out exactly the way it was supposed to with a traditional array_merge.
I know it's an old question but I'd like to add one more case I had recently with MongoDB driver queries and none of array_merge, array_replace nor array_push worked. I had a bit complex structure of objects wrapped as arrays in array:
$a = [
["a" => [1, "a2"]],
["b" => ["b1", 2]]
];
$t = [
["c" => ["c1", "c2"]],
["b" => ["b1", 2]]
];
And I needed to merge them keeping the same structure like this:
$merged = [
["a" => [1, "a2"]],
["b" => ["b1", 2]],
["c" => ["c1", "c2"]],
["b" => ["b1", 2]]
];
The best solution I came up with was this:
public static function glueArrays($arr1, $arr2) {
// merges TWO (2) arrays without adding indexing.
$myArr = $arr1;
foreach ($arr2 as $arrayItem) {
$myArr[] = $arrayItem;
}
return $myArr;
}
I stumbled upon this question trying to identify a clean way to join two assoc arrays.
I was trying to join two different tables that didn't have relationships to each other.
This is what I came up with for PDO Query joining two Tables. Samuel Cook is what identified a solution for me with the array_merge() +1 to him.
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM ".databaseTbl_Residential_Prospects."";
$ResidentialData = $pdo->prepare($sql);
$ResidentialData->execute(array($lapi));
$ResidentialProspects = $ResidentialData->fetchAll(PDO::FETCH_ASSOC);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM ".databaseTbl_Commercial_Prospects."";
$CommercialData = $pdo->prepare($sql);
$CommercialData->execute(array($lapi));
$CommercialProspects = $CommercialData->fetchAll(PDO::FETCH_ASSOC);
$Prospects = array_merge($ResidentialProspects,$CommercialProspects);
echo '<pre>';
var_dump($Prospects);
echo '</pre>';
Maybe this will help someone else out.
For me, this small snippet worked.
I have similar structures for both my arrays except the keys are a little different.
e.g
JSON 1 : {"sketchCount":{"2":{"A":50477}},"raw":{"2":{"A":70477}}}
JSON 2 : {"sketchCount":{"2":{"B":50477}},"raw":{"2":{"B":50477}}}
Desired Output JSON : {"sketchCount":{"2":{"A":70477,"B":50477}},"raw":{"2":{"A":70477,"B":50477}}}
Code
foreach($existingArray as $key => $possibleArray){
if(is_array($possibleArray)){
foreach($possibleArray as $index=> $value){
$combinedArray[$key][$index] = $value;
if(array_key_exists($key,$newArray) && array_key_exists($index,$newArray[$key])){
foreach($newArray[$key][$index] as $newKey=> $associatedValue){
$combinedArray[$key][$index][$newKey] = $associatedValue;
}
}
}
}
}
Related
So I have some code looking like this at the moment:
$filter = new \stdClass();
$queryObj = $this->getpost['filter'];
$filters = new \stdClass();
$filters->team = $queryObj['team'];
$filters->skill = $queryObj['skill'];
$filters->division = $queryObj['division'];
$filter->filters = $filters;
$users = $managerStatistics->getManagerDeliveryData($filter);
I fellt the need to do this because in the getManagerDeliveryData(§filter), there is a "foreach $filter->filters"..
Does anyone know how to do this in a better looking way? This looks messy to me but I'm not sure what to do here..
You could rewrite the way you build the data into a more compact format, casting each array definition to an object as needed...
$filter = (object) [
"filters" => (object) [ 'team' => $queryObj['team'],
'skill' => $queryObj['skill'],
'division' => $queryObj['division'] ]
];
If you cast an associative array to an object, it becomes a stdClass object with matching properties. Here's a generic example:
$arr = ['one' => 'foo', 'two' => 'bar', 'three' => 'meh'];
$obj = (object) $arr;
var_dump($obj);
This would give you:
object(stdClass)#2 (3) {
["one"] · string(3) "foo"
["two"] · string(3) "bar"
["three"] · string(3) "meh"
}
In your case, you could do the following, if you're hoping to not have to name your $queryObj keys/values one by one (which is necessary if e.g. the filter list isn't fixed, and therefore can't be hard-coded):
$filters = (object) $queryObj;
Obviously, every key/value pair in the source array then becomes a property/value pair in the object. If there are particular values you want to omit, either unset them or use array_intersect_key() etc. functions to only cast the desired keys. Suppose your $queryObject had a bunch of keys, but you only wanted the ones in your example, you could do this:
$keymap = ['team', 'skill', 'division'];
$filters = (object) array_intersect_key(array_flip($keymap), $queryObject);
I think this should be something simple, but I can't find a way to do it.
I have two arrays, one with colors and ids
$color_ids = [
'green' => [1,2,3],
'blue' => [4,5],
'red' => [6],
'pink' => [7,8,9],
'yellow' => [10]
];
and others with selection.
$select = ['green', 'red', 'yellow'];
Then I need the ids where intersects keys between $color_ids and $select. This should be the result (a simple linear array):
$results = [1,2,3,6,10];
I've tried this:
$result = array_values(array_intersect_key( $color_ids, array_flip($select ) ) );;
But I get multidimensional array:
array(3) {
[0]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
[1]=> array(1) { [0]=> int(6) }
[2]=> array(1) { [0]=> int(10) }
}
I get the same result with this:
$result = [];
foreach ($select as $key) {
if (isset($color_ids[$key]))
$result[] = $color_ids[$key];
}
How can I get a simple linear array with ids?
1) Iterate over the key array
2) Merge all the arrays into one using array_merge
$select = ['green', 'red', 'yellow'];
$finalArray=[];
foreach($select as $value){
$finalArray= array_merge($finalArray,$color_ids[$value]);
}
echo "<pre>";
print_r($finalArray);
Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 6
[4] => 10
)
You can use array_merge with the ... operator which is a common flattening technique demonstrated here.
array_merge(...$result);
Array Merge documentation.
Splat Operator documentation.
with foreach
$result = [];
foreach($color_ids as $color => $ids){
$result = array_merge($result, in_array($color, $select) ? $ids : []);
}
If you are looking for a fully "functional style" solution, here's one.
Set up your filtering array ($select) so that it has keys like the master array's keys. In other words, flip the values into keys.
Then swiftly filter the master array using array_intersect_key().
Then to flatten the remaining data, prepend the splat/spread operator and call array_merge().
Until you are on a php version that allows associative arrays to be spread, then you'll need to call array_values() to reindex the first level keys so that the spread operator doesn't choke.
Code: (Demo)
var_export(
array_merge(
...array_values(
array_intersect_key(
$color_ids,
array_flip($select)
)
)
)
);
Or if you prefer jumble the syntax into a single line:
var_export(array_merge(...array_values(array_intersect_key($color_ids, array_flip($select)))));
Although a foreach() may perform a few nanoseconds faster than functional programming, you are never going to notice on such small data sets. One benefit of this coding style is that you don't have to name any temporary variables to push qualifying data into. In other words you can feed this directly into a return statement inside of a function which I find to be very tidy.
Alternatively, if you don't mind generating a result variable, then iterated array_push() calls while spreading the matching nominated color_id value is pretty simple. This technique is different in that if $select contains a color that is not a key in $color_id, then php will bark at you!
Code: (Demo)
$result = [];
foreach ($select as $color) {
array_push($result, ...$color_ids[$color]);
}
var_export($result);
Both techniques offer the same result.
This question already has answers here:
Generate an associative array from an array of rows using one column as keys and another column as values
(3 answers)
Closed 5 months ago.
The Microsoft QnAMaker API is returning a JSON key/value array (Metadata) in the following format:
$array = [[
"name" => "someName1",
"value" => "someValue1",
],
[
"name" => "someName2",
"value" => "someValue2",
],
..etc..
];
How do i transform it to be in the following more usable format:
$array = [
"someName1" => "someValue1",
"someName2" => "someValue2",
..etc..
];
I know I can do it using a loop... Is there a way to leverage on built in functions?
If a loop is the only way, how would you write it and why (performance/readibility/etc.)?
If it looks JSONish, array_column helps. Simply:
<?php
var_export(array_column($array, 'value', 'name'));
Output:
array (
'someName1' => 'someValue1',
'someName2' => 'someValue2',
)
This uses a combination of array_map() to re-map each element and then array_merge() to flatten the results...
print_r(array_merge(...array_map(function($data)
{ return [ $data['name'] => $data['value']]; }
, $array)));
It's not very elegant and would be interesting to see other ideas around this.
Which gives...
Array
(
[someName1] => someValue1
[someName2] => someValue2
)
There isn't really a way besides a loop, so just loop through the array, and create a new array the way you need it.
$new_array = [];
foreach($array as $row) {
$new_array[$row['name']] = $row['value'];
}
print_r($new_array);
There may be a few functions you can tie together to do what you want, but in general, the loop would probably be more readable and easier in overall.
As my previous answer was a dupe of GrumpyCroutons, I thought I'd rewrite with many array functions for good measure. (But don't use this, just do a simple foreach).
<?php
array_walk($array, function($v) use (&$result) {
$result[array_shift($v)] = array_values($v)[0];
});
var_export($result);
Output:
array (
'someName1' => 'someValue1',
'someName2' => 'someValue2',
)
This works:
$res = [];
array_walk($array, function(&$e) use(&$res) {
$res[$e['name']] = $e['value'];
unset($e); // this line adds side effects and it could be deleted
});
var_dump($res);
Output:
array(2) {
["someName1"]=> string(10) "someValue1"
["someName2"]=> string(10) "someValue2"
}
You can simply use array_reduce:
<?php
$output = array_reduce($array, function($a, $b) {
$a[$b['name']] = $b['value'];
return $a;
});
var_export($output);
Output:
array (
'someName1' => 'someValue1',
'someName2' => 'someValue2',
)
While getting a shift on (a non-foreach):
<?php
$c = $array;
while($d = array_shift($c))
$e[array_shift($d)] = array_shift($d);
var_export($e);
Output:
array (
'someName1' => 'someValue1',
'someName2' => 'someValue2',
)
Although it suggests in the comments in the manual that shifting is more expensive than popping. You could replace the initial assignment to $c above with an array_reverse and the while-shift with a while-pop.
However, either approach is probably lousy compared to a foreach, but here for who knows whos amusement.
Is there a fast way to return a key when you know its value in PHP?
For example, if you have:
$Numbers = (object) array ( "0" => 0, "1" => 1, "2" => 3, "3" => 7, "4" => 13 );
is there a way to return:
echo re(13); // Print 4
One way I could think of is to build a function specifically for this, but I was wondering if there is a better way.
There is array_search:
$key = array_search(13, (array) $Numbers);
See http://ua2.php.net/array_search
As several other people have mentioned, array_search does what you asked. But if you want an array of ALL the keys that contain the value instead of only the first, you can use array_keys.
print_r(array_keys($Numbers, 13)); // print Array ( [0] => 4 )
http://www.php.net/manual/en/function.array-keys.php
if you are certain that you have unique keys:
$flipped = array_flip($array);
$key = $flipped[$knownValue];
return $key;
Otherwise, use array_search:
return array_search($knownValue, $array);
The first approach may be better if you do a number of lookups, and have unique values. The second approach returns the first matching key in case of multiple values.
http://php.net/array_search
echo array_search($valToSearch, (array) $Numbers);
http://php.net/manual/en/function.array-search.php
Hi I have an array, I need to change the keys, in an orderly manner but don't change the order the values are. e.g.
$a = array (
0=>'h',
1=>'blabla',
2=>'yes'
);
I used
unset($a[1]);
but i need the key to restart calculating the keys
0,1,2 ... etccc
so i don't end up with:
array(
0 => 'h',
2 => 'yes'
)
but it should come return:
array(
0 => 'h',
1 => 'yes'
)
You need to apply array_values on your array to re-index.
$a = array_values($a);
Bonus: If you also need to order your values you can use sort and it too will re-index your array.
Note: By using any of array_values or sort you will loose any string keys you may have.
Call array_values on it:
$a = array (
0=>'h',
1=>'blabla',
2=>'yes'
);
unset($a[1]);
$a = array_values($a);
var_dump($a);
/*
array(2) {
[0]=>
string(1) "h"
[1]=>
string(3) "yes"
}
*/
You can also use array_splice() instead of unset(), which will automatically reindex the array elements:
$a = array (
0=>'h',
1=>'blabla',
2=>'yes'
);
array_splice($a,1,1);
var_dump($a);