I have a maybe stupid question?
I have three arrays. And I want to get different values from the first and third array. I created the following code but the returned values are wrong.
function ec($str){
echo $str.'<br>';
}
$arr1 = array( array(
'letter' => 'A',
'number' => '1'
),
array(
'letter' => 'B',
'number' => '2'
),
array(
'letter' => 'C',
'number' => '3'
)
);
$arr2 = array( array(
'letter' => 'A',
'number' => '1'
),
array(
'letter' => 'B',
'number' => '2'
)
);
$arr3 = array( array(
'letter' => 'D',
'number' => '4'
),
array(
'letter' => 'E',
'number' => '5'
)
);
$mergeArr = array_merge($arr1,$arr3);
foreach ($mergeArr as $kMerge => $vMerge){
foreach ($arr2 as $val2){
if($val2['letter'] != $mergeArr[$kMerge]['letter']){
ec($mergeArr[$kMerge]['letter']);
}
}
}
The result of this code is:
A
B
C
C
D
D
E
E
The result I want:
C
D
E
Thanks in advance.
Based on the result you are looking for, this should do it:
$mergeArr = array_merge($arr1,$arr3);
$res = array_diff_assoc($mergeArr, $arr2);
var_dump($res);
See the snippet on codepad.
Try this instead of your foreach's:
$diff = array_diff($mergeArr, $arr2);
foreach( $diff as $d_k => $d_v ) {
ec($d_v['letter']);
}
If I understand what you are trying to do correctly, this function should do the job:
function find_unique_entries () {
$found = $repeated = array();
$args = func_get_args();
$key = array_shift($args);
foreach ($args as $arg) {
if (!is_array($arg)) return FALSE; // all arguments muct be arrays
foreach ($arg as $inner) {
if (!isset($inner[$key])) continue;
if (!in_array($inner[$key], $found)) {
$found[] = $inner[$key];
} else {
$repeated[] = $inner[$key];
}
}
}
return array_diff($found, $repeated);
}
Pass the key you are searching to the first arguments, then as many arrays as you like in the subsequent arguments. Returns an array of results or FALSE on error.
So your usage line would be:
$result = find_unique_entries('letter', $arr1, $arr2, $arr3);
See it working
Related
Help:
Array format like this:
$arr=array(
array('element1'=>'a','element2'=>1),
array('element1'=>'b','element2'=>2),
array('element1'=>'a','element2'=>2),
array('element1'=>'b','element2'=>3),
);
Synthesis is needed,how to change it like:
$arr=array(
array('element1'=>'a','element2'=>array(1,2)),
array('element1'=>'b','element2'=>array(2,3)),
);
$new = array();
foreach ($arr as $key => $value) {
$new[$value['element1']][] = $value['element2'];
}
$new2 = array();
foreach($new as $k=>$v){
$new2[] = array('element1'=>$k,'element2'=>$v);
}
print_r($new2);
Result
array(
array('element1' => 'a', 'element2' => array(0 => 1, 1 => 2)),
array('element1' => 'b', 'element2' => array(0 => 2, 1 => 3)),
)
In php is there a way to get an element from each sub array without having to loop - thinking in terms of efficiency.
Say the following array:
$array = array(
array(
'element1' => a,
'element2' => b
),
array(
'element1' => c,
'element2' => d
)
);
I would like all of the 'element1' values from $array
There are a number of different functions that can operate on arrays for you, depending on the output desired...
$array = array(
array(
'element1' => 'a',
'element2' => 'b'
),
array(
'element1' => 'c',
'element2' => 'd'
)
);
// array of element1s : array('a', 'c')
$element1a = array_map(function($item) { return $item['element1']; }, $array);
// string of element1s : 'ac'
$element1s = array_reduce($array, function($value, $item) { return $value . $item['element1']; }, '');
// echo element1s : echo 'ac'
array_walk($array, function($item) {
echo $item['element1'];
});
// alter array : $array becomes array('a', 'c')
array_walk($array, function(&$item) {
$item = $item['element1'];
});
Useful documentation links:
array_map
array_reduce
array_walk
You can use array_map.
Try code below...
$arr = $array = array(
array(
'element1' => a,
'element2' => b
),
array(
'element1' => c,
'element2' => d
)
);
print_r(array_map("getFunc", $arr));
function getFunc($a)
{
return $a['element1'];
}
See Codepad.
But I think array_map will also use loop internally.
If you're running PHP 5.5 (currently the beta-4 is available), then the following
$element1List = array_column($array, 'element1');
should give $element1List as an simple array of just the element1 values for each element in $array
$array = array(
array(
'element1' => a,
'element2' => b
),
array(
'element1' => c,
'element2' => d
)
);
$element1List = array_column($array, 'element1');
print_r($element1List);
gives
Array
(
[0] => a
[1] => c
)
Without loop? Recursion!
$array = array(
array(
'element1' => 'a',
'element2' => 'b'
),
array(
'element1' => 'c',
'element2' => 'd'
)
);
function getKey($array,$key,$new = array()){
$count = count($array);
$new[] = $array[0][$key];
array_shift($array);
if($count==1)
return $new;
return getKey($array,$key,$new);
}
print_R(getKey($array,'element1'));
As I understood from Wikipedia Recursion is not a loop.
I've been searching for this for some days but cant seem to find the anwer.
I have an array like
$startArray = Array(array('name' => 'A', 'hierarchy' => '1'),
array('name' => 'B', 'hierarchy' => '1.2'),
array('name' => 'C', 'hierarchy' => '1.3'),
array('name' => 'D', 'hierarchy' => '1.3.1')
);
and i would like to go to
$endResult =
array(
array('name' => 'A',
'children' => array(
array('name'=> 'b'),
array('name'=> 'c',
'children' => array('name' => 'D')
)
)
);
Any suggestions?
Thanks
Okay here is a long solution, which you might want to wrap into a function, perhaps. Just copy and paste this inside a blank document and check the result in a browser.
<pre>
<?php
$orig = array(
array('name' => 'A', 'hierarchy' => '1'),
array('name' => 'B', 'hierarchy' => '1.2'),
array('name' => 'C', 'hierarchy' => '1.3'),
array('name' => 'D', 'hierarchy' => '1.3.1')
//,array('name' => 'E', 'hierarchy' => '1.2.1')
//,array('name' => 'F', 'hierarchy' => '2.1')
);
function special_sort($arr1,$arr2) {
$h1 = $arr1['hierarchy'];
$h2 = $arr2['hierarchy'];
$ch1 = count($h1);
$ch2 = count($h2);
if ($ch1 < $ch2) return -1;
if ($ch1 > $ch2) return 1;
return $h1 > $h2 ? 1 : ($h1 < $h2 ? -1 : 0);
}
// this first checks lengths and then values
// so 1.3 gets -1 against 1.2.1 whereas
// 1.3.2 still gets 1 against 1.3.1
$temp = $orig;
// temporary array to keep your original untouched
foreach ($temp as &$arr) {
$arr['hierarchy'] = explode('.',$arr['hierarchy']);
// turn hierachy numbers into arrays for later
// sorting purposes
}
unset($arr);
// get rid of the reference used in the loop
usort($temp,'special_sort');
// sort by the sort function above
echo '<h2>$orig</h2>'; print_r($orig);
echo '<h2>$temp</h2>'; print_r($temp);
// for you to see what it looks like now
$res = array();
// our final array
// by the following loop we're using the hierarcy
// numbers as keys to push into the result array
foreach ($temp as $arr) {
$h = $arr['hierarchy'];
if (count($h) == 1) {
// this is for those with single hierarchy
// numbers such as 1, 2, etc.
$res[$h[0]] = array('name'=>$arr['name']);
continue;
}
if (!isset($res[$h[0]]))
$res[$h[0]] = array('name'=>'');
// if, say this is 2.1 but there is no 2 in the array then
// we need to create that. see the last commented item in
// the original array. uncomment it to see why I wrote this
$newLoc =& $res[$h[0]];
// reference of the new place in result
// array to push the item
for ($i = 1; $i < count($h); $i++) {
if (!isset($newLoc['children']))
$newLoc['children'] = array();
// create children array if it doesn't exist
if (!isset($newLoc['children'][$h[$i]]))
$newLoc['children'][$h[$i]] = array();
// create children[hierarch key] array if it doesn't exist
$newLoc =& $newLoc['children'][$h[$i]];
// update reference
}
$newLoc = array('name'=>$arr['name']);
// assign the new name to this reference
unset($newLoc);
// get rid of the reference
}
unset($temp);
// get rid of the array now that we're done with it
echo '<h2>$res</h2>'; print_r($res);
function fix_keys($array) {
foreach ($array as $k => $val) {
if (is_array($val)) $array[$k] = fix_keys($val);
}
if(is_numeric($k)) return array_values($array);
return $array;
}
// function courtesy of Lobos,
// http://stackoverflow.com/a/12399408/913097
$endRes = fix_keys($res);
// create the end result array. this is actually
// a copy of the $res array except the numeric
// keys were reset.
unset($res);
// get rid of the last unused array
echo '<h2>$endRes</h2>'; print_r($endRes);
?>
</pre>
you do not have the correct array, the values will be rewritten. You need approximately the:
$arr = array(
array('name' => 'a', 'hierarchy' => '1'),
array('name' => 'b', 'hierarchy' => '1.2'),
);
EDIT: making it clear that I need it for multidimensional arrays (at any depth level)
I need to cut down the size of an array to get only a portion of it, but this needs to be done recursively. For example, take the following case:
$a = array(
'a',
'b' => array(
'x' => array(
'aleph',
'bet'
),
'y'),
'c',
'd',
'e'
);
what I need is that after copying only 4 elements I'll get the following resulted array:
$a = array(
'a',
'b' => array('x' => array(
'aleph'
),
),
);
and not...
$a = array(
'a',
'b' => array('x' => array(
'aleph',
'bet'
),
'y'),
'c',
'd',
);
How do I achieve this?
Thanks!
You can try **Note : dual-dimensional
$a = array("a","b" => array('x','y'),"c","d","e");
$new = __cut($a);
function __cut($array, $max = 4) {
$total = 0;
$new = array();
foreach ( $array as $key => $value ) {
if (is_array($value)) {
$total ++;
$diff = $max - $total;
$slice = array_slice($value, 0, $diff);
$total += count($slice);
$new[$key] = $slice;
} else {
$total ++;
$new[$key] = $value;
}
if ($total >= $max)
break;
}
return $new;
}
var_dump($new);
Output
array
0 => string 'a' (length=1)
'b' =>
array
0 => string 'x' (length=1)
1 => string 'y' (length=1)
function arrayTrim($array, $size, $finalArray = null){
global $count;
foreach ($array AS $key => $val){
if($size == $count)
return $finalArray;
$count++;
if(is_array($val)){
$finalArray[$key] = array();
$finalArray[$key] = arrayTrim ($val, $size, $finalArray[$key]);
}
else
$finalArray[$key] = $val;
}
return $finalArray;
}
$a = array( "a"=> array('xa', 'ya'), "b" => array('x', 'y'), "c", "d", "e" );
print_r(arrayTrim($a, 4));
should work fine
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()