Keys and Values re-formatting in PHP - php

Please read the whole question before attempting to answer. If I have two associative arrays where some values match just once:
$array1 = ['key1' => 'value1', 'key3' => 'value2', etc...];
$array2 = ['key2' => 'value1', 'key4' => 'value2', etc...];
but $array2 is longer than $array 1, and in those cases the keys don't have values:
$array1 = ['key1' => 'value1', 'key3' => 'value2'];
$array2 = ['key2' => 'value1', 'key4' => 'value2', 'key5' => 'value3'];
Then how can I combine them to get the following result:
$array3 = [
'value1' => [$myconstant => key2],
'value2' => [$myconstant => key4],
'value3' => [$myconstant => ''],
etc...];
Notice that in cases where there is no match, an empty string is used instead of the key in the embedded associative array. In fact, the only reason why $array1 is necessary is because I need to know when there is a match with $array2 to get the correct format.
The values will not repeat themselves along the etc... chain.
I'm using Laravel and am trying to use Collections, but basic PHP solutions are okay too. Thank you very much.

I guess the biggest hurdle you have is how to transform those values in keys and keys into values. array_flip is the answer to that problem. Once you have that, you can solve your problem with a simple foreach loop.
$myconstant = 'foo';
$array1 = ['key1' => 'value1', 'key3' => 'value2'];
$array2 = ['key2' => 'value1', 'key4' => 'value2', 'key5' => 'value3'];
// array_flip switches keys and values in an array
$flip1 = array_flip($array1);
$flip2 = array_flip($array2);
$array3 = [];
foreach($flip2 as $key => $value) {
if(!isset($flip1[$key])) {
$array3[ $key ] = [ $myconstant => '' ];
} else {
$array3[ $key ] = [ $myconstant => $value ];
}
}
Laravel Collections have a flip() method, too. That might help you translating the script into Laravel.

<?php
$array1 = ['key1' => 'value1', 'key3' => 'value2'];
$array2 = ['key2' => 'value1', 'key4' => 'value2', 'key5' => 'value3'];
function x (array $a= array(), array $b = array()) {
$array = array();
$index = new ArrayObject($a);
$seed = new ArrayObject($b);
$a_it = $index->getIterator();
$b_it = $seed->getIterator();
while ($a_it->valid()) {
$x = $a_it->current();
$y = ($b_it->valid()) ? $b_it->current() : NULL;
if ($y !== NULL) {
# there is a value to compare against
if ($x === $y) {
$array["{$x}"] = array('myConst'=>$a_it->key());
}
$b_it->next();
} else {
# there is no value to compare against
$array["{$x}"] = array('myConst'=> '');
}
$a_it->next();
}
return $array;
}
$read = x($array2, $array1);
print_r($read);

Related

loop through two arrays with different sizes and find equal items

I have two arrays with different sizes and I want to do some action when two items are equal.
my arrays may look like this
array_1 = { 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' }
array_2 = { 'key2' => 'value2' }
in the example above I want to perform an action when key2 from array_1 and key2 from array_2 are found.
Currently I am using 2 foreach loops to do this. Something like this:
foreach ($block->getSettingsNoDefaults() as $baseKey => $value) {
$found = false;
foreach ($blockData->settings as $saveKey => $value) {
if($baseKey == $saveKey) {
$found = true;
break;
}
}
if(!$found) {
$block->removeSetting($baseKey);
}
}
Is there a way to use some other more elegant way to do this insead of two foreach loops to compare all values from one array to all values from second array and then act if they match?
I thought first of using php's array_map("myfunction",$array_1 ,$array_2) to do this but it does not seem like right function in my case, since it will loop through both arrays and only compare elements that are at the same index.
Is there any other function that I can use in my case so I can make my code more elagant then using multiple forloops.
You can use array_key_exists and one foreach loop.
Solution
$array_1 = [ 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3' ];
$array_2 = [ 'key2' => 'value2' ];
foreach($array_2 as $key => $item){
if(array_key_exists($key, $array_1)){
echo "Match found.";
}
}
Updated Answer I found that you can use array_intersect_key($a1,$a2) instead
$array_1 = array('key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3');
$array_2 = array('key2' => 'value2' );
$result = array_intersect_key($array_1,$array_2);
print_r($result);

Merge two arrays keeping the first array values as keys and second array values as values

Basically i have an array of key mappings (actually translations) and an array of data values. I want to essentially replace the keys of the second array with the values of the first array.
E.G.:
$array1 = array(
'key1' => 'newkey1',
'key2' => 'newkey2',
'key3' => 'newkey3',
'key4' => 'newkey4'
);
$array2 = array(
'key1' => 'data1',
'key2' => 'data2',
'key3' => 'data3',
'key4' => 'data4',
'key5' => 'data5',
'key6' => 'data6'
);
$result = array(
'newkey1' => 'data1',
'newkey2' => 'data2',
'newkey3' => 'data3',
'newkey4' => 'data4'
);
Edit: Added excess data to second array
If you're sure that the number of elements in both the arrays are same, you can simply use array_combine():
$result = array_combine($array1, $array2);
If your second array contains excess elements, then you could use array_intersect_key() to remove them before using array_combine():
$values = array_intersect_key($array1, $array2);
$result = array_combine($array1, $values);
Demo

Best way to slice multidimensional array on the basis of keys in PHP?

I have an result array like this:-
$array = array(
'key1' => array('...'),
'key2' => array('...'),
'key3' => array('...'),
'key4' => array('...'),
.
.
.
.
'keyn' => array('...')
);
I need to get 5 elements from above array. first time key1 to key5, key6 to key10
and so on...... On the basis of condition I need to perform operation on this.
I need output :-
$array = array(
'key1' => array('...'),
'key2' => array('...'),
'key3' => array('...'),
'key4' => array('...'),
'key5' => array('...')
);
I can get value if my key value directly $array['key1']....$array['key5'] but if key is unknown value than
I am facing problem.
Thanks in advance.
To iterate over such an array you can use array_slice() in this manner:
$n = count($array);
$len = 5;
for ($i = 0; $i + $len <= $n; $i += $len) {
$chunk = array_slice($array, $i, $len, true);
// do work on $chunk
}
you can just splice or slice the first 5 items off of the array.
<?php
$array = array(
'key1' => array('...'),
'key2' => array('...'),
'key3' => array('...'),
'key4' => array('...'),
'key5' => array('...'),
'key6' => array('...'),
'key7' => array('...')
);
$arraySlice1 = array_slice($array, 0, 5);
$arraySlice2 = array_splice($array, 0, 5);
Slice will leave $array intact and $array will still hold 7 items, splice will remove the returned results from $array, so $array will only hold key6 and key7
Edit: A better way is array_slice. See this question. Example:
$fifthElement = array_slice($array,4,1); //will get the 5th element
You can use foreach in a way that gives you the keys and the associated values. So, to get the fifth key-value-pair, you could write:
$i = 1;
foreach($array as $key => $value)
{
if($i == 5)
{
echo "Fifth Key=".$key." value=".$value."\n";
}
$i++;
}
array_slice surely works for you
$first_five_elements = array_slice($array, 0, 5);
Here is codepad

php - sort an array by key to match another array's order by key

I have two arrays, both have the same keys (different values) however array #2 is in a different order. I want to be able to resort the second array so it is in the same order as the first array.
Is there a function that can quickly do this?
I can't think of any off the top of my head, but if the keys are the same across both arrays then why not just loop over the first one and use its key order to create a new array using the the values from the 2nd one?
$arr1 = array(
'a' => '42',
'b' => '551',
'c' => '512',
'd' => 'gge',
) ;
$arr2 = array(
'd' => 'ordered',
'b' => 'is',
'c' => 'now',
'a' => 'this',
) ;
$arr2ordered = array() ;
foreach (array_keys($arr1) as $key) {
$arr2ordered[$key] = $arr2[$key] ;
}
You can use array_replace
$arr1 = [
'x' => '42',
'y' => '551',
'a' => '512',
'b' => 'gge',
];
$arr2 = [
'a' => 'ordered',
'x' => 'this',
'y' => 'is',
'b' => 'now',
];
$arr2 = array_replace($arr1, $arr2);
$arr2 is now
[
'x' => this,
'y' => is,
'a' => ordered,
'b' => now,
]
foreach(array_keys($array1) as $key)
{
$tempArray[$key] = $array2[$key];
}
$array2 = $tempArray;
I am not completely sure if this is what your after. anyways as long as the the array remains the same size, than this should work for you.
$gamey = array ("wow" => "World of Warcraft", "gw2" => "Guild Wars2", "wiz101" => "Wizard 101");
$gamex = array ("gw2" => "best game", "wiz101" => "WTF?", "wow" => "World greatest");
function match_arrayKeys ($x, $y)
{
$keys = array_keys ($x);
$values = array_values ($y);
for ($x = 0; $x < count ($keys); $x++)
{
$newarray [$keys[$x]] = $y[$keys[$x]];
}
return $newarray;
}
print_r (match_arrayKeys ($gamey, $gamex));
Output
[wow] => World greatest
[gw2] => best game
[wiz101] => WTF?
Try this
CODE
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
OUTPUT
a = orange
b = banana
c = apple
d = lemon
Check the php manual for ksort()

Get part of an array

I have an array:
$array = array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
'key4' => 'value4',
'key5' => 'value5',
);
and I would like to get a part of it with specified keys - for example key2, key4, key5.
Expected result:
$result = array(
'key2' => 'value2',
'key4' => 'value4',
'key5' => 'value5',
);
What is the fastest way to do it ?
You need array_intersect_key function:
$result = array_intersect_key($array, array('key2'=>1, 'key4'=>1, 'key5'=>1));
Also array_flip can help if your keys are in array as values:
$result = array_intersect_key(
$array,
array_flip(array('key2', 'key4', 'key5'))
);
You can use array_intersect_key and array_fill_keys to do so:
$keys = array('key2', 'key4', 'key5');
$result = array_intersect_key($array, array_fill_keys($keys, null));
array_flip instead of array_fill_keys will also work:
$keys = array('key2', 'key4', 'key5');
$result = array_intersect_key($array, array_flip($keys));
Only way I see is to iterate the array and construct a new one.
Either walk the array with array_walk and construct the new one or construct a matching array and use array_intersect_key et al.

Categories