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.
Related
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);
I have this array :
$arr = array(0 => array('id' => "AMO"), 1 => array('id' => "PAT"));
And I would like to obtain this one :
array(
'AMO' => array(),
'PAT' => array()
)
How could I do this, in the shortest way possible ?
I can do it with an array_map, followed by an array_flip and next an array_walk .. but too long.
array_column to extract the keys and array_fill_keys to create the new array:
$arr = array(0 => array('id' => "AMO"), 1 => array('id' => "PAT"));
$res = array_fill_keys(array_column($arr, 'id'), []);
simply loop over array and make its id to new array key
$arr = array(0 => array('id' => "AMO"), 1 => array('id' => "PAT"));
foreach($arr as $value)
{
$new_arr[$value['id']] = array();
}
print_r($new_arr);
DEMO
I dont know what is the logic behind this, but you can try this one.
Here we are using array_combine, array_keys and array_fill
Try this code snippet here
$result= array_combine(
array_column($array,"id"),//getting column id
array_fill(0, count($array), array())//mapping that keys with empty array
);
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);
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
Assume a master array which is already sorted in ASCENDING order:
$values = array('value1', 'value2', 'value3', 'value4', 'value5', 'value6');
And another array with the keys(indexes) being ordered per some specific requirement.
$keys = array(0, 2, 1, 5);
Required Logic: should create an array say $output
beginning with elements of $values who's indexes are stored $keys preserving the order of indexes.
remaining elements of $values shall be appended in the rear in ascending order.
e.g. 1
$values = array('value1', 'value2', 'value3', 'value4', 'value5', 'value6');
$keys = array(0, 2, 1, 5);
$output = array('value1', 'value3', 'value2', 'value6', 'value4', 'value5');
e.g. 2
$values = array('value1', 'value2', 'value3', 'value4', 'value5', 'value6');
$keys = array(5);
$output = array('value6', 'value1', 'value2', 'value3', 'value4', 'value5');
e.g. 3
$values = array('value1', 'value2', 'value3', 'value4', 'value5', 'value6');
$keys is empty, no keys(indexes).
$output = array('value1', 'value2', 'value3', 'value4', 'value5', 'value6');
I've $values and $keys arrays. I just need to figure out how to create $output array. I'm pretty sure there will need to be a foreach loop on the $values array for this to work.
I'm running into a wall here trying to figure this thing out...
Try this...
Basically parsing the $values array and pulling the relevant value out.
Unsetting the array as we go to leave only the values which were not sorted.
The remaining items in the array will be merged after the loop. with array_merge.
Unsetting the array doesn't change the index values, which is useful in this situation.
There will be errors if there are more $keys than $values though. Need to add some error checks.
$values = array('value1', 'value2', 'value3', 'value4', 'value5', 'value6');
$keys = array(0, 2, 1, 5);
foreach ($keys AS $key) {
$tempOutput[] = ($values[$key])?$values[$key]:'';
unset($values[$key]);
}
$output = array_merge($tempOutput, $values);