I have this array:
$array[] = [
'a' => $a,
'b' => $b,
];
The array contains of let's say 10 entries, $a can be in there with the same value many times and I need only one of those entries for a db insert.
I can't manage to get array_unique working as it throws
array to string conversion
error when trying to use it like
$result = array_unique($array);
I now made a little foreach loop that feels just wrong to do so:
$z = [];
foreach ($array as $x) {
if (#!in_array($x['a'],$z)) {
$z[] = $x['a'];
}
}
and I use $z for the insert thereafter.
Can someone point me in the right direction of how to distinct my array values?
This should work for you:
($result = array_unique($array); this didn't worked, because you have a multidimensional array!)
<?php
//Example data
$array[] = [
'a' => 1,
'b' => 1,
'c' => 1,
'd' => 2,
'e' => 2,
];
$array = array_map("array_unique", $array);
print_r($array);
?>
Output:
Array ( [0] => Array ( [a] => 1 [d] => 2 ) )
Based on your array that is two dimensional, you would need:
$array = array_map('array_unique', $array);
Or if you don't need a two dimensional array, just use:
$array = [
'a' => $a,
'b' => $b,
];
And then: $array = array_unique($array);
One thing not mentioned is that arrays are built in unique, if you can manage the keys for them yourself. Associative arrays can only have the key once. So I like to do is use the primary key or a unique identifier for the key.
You can't have an array with the same keys like this.
array(
'a' => $a
'a' => $b
)
Because the key a is already a unique identifier. If you follow.
Related
If I have an associative array that is structured like
(
1 => 'a',
2 => 'b',
0 => 'c'
)
where all of the keys are numeric, will array_values ALWAYS guarantee that the values occur chronologically, in the new array, based on their previous keys' values, i.e. ['c', 'a', 'b']?
If not, how can I accomplish this instead?
No, array_values() will not reorder the values in any way. It doesn't care about keys.
Its effective implementation is basically this:
function array_values_impl(array $array)
{
$newArray = [];
foreach ($array as $item) {
$newArray[] = $item;
}
return $newArray;
}
If you want to sort the array using the keys, use ksort().
You can accomplish by first sorting the array with keys and getting values by array_values function.
For example
$array = array(
1 => 'a',
2 => 'b',
0 => 'c'
);
ksort($array);
print_r(array_values($array));
Output:
Array
(
[0] => c
[1] => a
[2] => b
)
I am using the Flot jQuery plugin to create a graph on how many visitors there have been per platform. I would like to create a 4th line with total visitors, calculated by previously retrieved data.
I need to combine several multi-dimensional Indexed arrays, but not simply merging them recursively. I.E:
$arr1 = [[2016/05/04,2],[2016/05/03,4],[2016/05/02,6]];
$arr2 = [[2016/05/04,1],[2016/05/03,3],[2016/05/02,2]];
$arr3 = [[2016/05/04,6],[2016/05/03,7],[2016/05/02,8]];
The output should be:
$arrTotal = [[2016/05/04,9],[2016/05/03,14],[2016/05/02,16]];
How do I accomplish this in a (fairly) simple way?
First of all, you cannot declare your dates the way you did:
$arr1 = [[2016/05/04,2],[2016/05/03,4],[2016/05/02,6]];
Because it's going to take 2016, divide it by 5 then divide it by 4. You need to put them into quotes.
$arr1 = [['2016/05/04',2],['2016/05/03',4],['2016/05/02',6]];
But to create an associative array, you should do it this way:
$arr1 = array('2016/05/04' => 2, '2016/05/03' => 4, '2016/05/02' => 6);
$arr2 = array('2016/05/04' => 1, '2016/05/03' => 3, '2016/05/02' => 2);
$arr3 = array('2016/05/04' => 6, '2016/05/03' => 7, '2016/05/02' => 8);
Now all you want to do, is loop through each array and sum them up.
$merge = array();
function mergeArray(Array &$merge, Array $array){
// Loop through each key and value
foreach($array as $key => $value)
// Make sure the value is numeric
if(is_numeric($value)){
if(!isset($merge[$key]))
$merge[$key] = $value;
else
$merge[$key] += $value;
}
}
mergeArray($merge, $arr1);
mergeArray($merge, $arr2);
mergeArray($merge, $arr3);
And now if you dump the $merge:
array(3) {
["2016/05/04"]=>
int(9)
["2016/05/03"]=>
int(14)
["2016/05/02"]=>
int(16)
}
Build a method that will sum the values by respecting the keys of existing values.
$arr1 = array('2016/05/04'=>2,'2016/05/03'=>4,'2016/05/02'=>6);
$arr2 = array('2016/05/04'=>1,'2016/05/03'=>3,'2016/05/02'=>2);
$arr3 = array('2016/05/04'=>2,'2016/05/03'=>7,'2016/05/02'=>8);
function array_sum(&$new_arr,$arr) {
foreach ($arr as $date_key => $num_value) {
// initialize date in new array with 0, if not done previously
if (! isset($new_arr[$date_key])) { $new_arr[$date_key] = 0; }
// add number for indexed element of array
$new_arr[$date_key] += $num_value;
}
}
$new_arr = array();
array_sum($new_array,$arr1);
array_sum($new_array,$arr2);
array_sum($new_array,$arr3);
You are trying to sum up every second value from each nested array relatively to their position in the parent array.There's a short and simple solution using array_map, array_sum and array_column functions:
$groupped = array_map(null, $arr1,$arr2,$arr3);
$result = array_map(function($v){
return [$v[0][0], array_sum(array_column($v, 1))];
}, $groupped);
print_r($result);
The output:
Array
(
[0] => Array
(
[0] => 2016/05/04
[1] => 9
)
[1] => Array
(
[0] => 2016/05/03
[1] => 14
)
[2] => Array
(
[0] => 2016/05/02
[1] => 16
)
)
This is my code:
$a = array(
array("a" => 1, "b" => 2),
array("x" => 2, "a" => 2),
array("d" => 100, "a" => 3, "b" => 2, "c" => 3)
);
$myArray = array();
foreach ($a as $arr) {
$myArray[] = $arr['a'];
}
print_r($myArray);
So, I get
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Is there any other way to do this without for loop? like using one are two PHP array functions to get the same response.
The above is correct but still if there is any other better way to do this that would be appreciable! Because the same array $a in my code is required to be iterate many times. If I have any better way to do this so I can reduce another iteration( PHP still does iteration in built-in fns, I don't bother it).
Yes (since you're on PHP 5.4, array_column() isn't an option),
$result = array_map(function($x)
{
return $x['a'];
}, $a);
But note, this will still use loop internally (i.e. in the end it always be a loop)
I know how to insert it to the end by:
$arr[] = $item;
But how to insert it to the beginning?
Use array_unshift($array, $item);
$arr = array('item2', 'item3', 'item4');
array_unshift($arr , 'item1');
print_r($arr);
will give you
Array
(
[0] => item1
[1] => item2
[2] => item3
[3] => item4
)
In case of an associative array or numbered array where you do not want to change the array keys:
$firstItem = array('foo' => 'bar');
$arr = $firstItem + $arr;
array_merge does not work as it always reindexes the array.
Since PHP7.4 you can use the spread opperator, very similar to JavaScript
$arr = [$item, ...$arr];
https://wiki.php.net/rfc/spread_operator_for_array
A few more examples:
// Add an item before
$arr = [$item, ...$arr];
// Add an item after
$arr = [...$arr, $item];
// Add a few more
$arr = [$item1, $item2, ...$arr, $item3];
// Multiple arrays and and items
$arr = [$item1, ...$arr1, $item2, ...$arr2, $item3];
Note: this is only possible with int keys, not for associative arrays.
Note2: The keys are not kept.
BREAKING Example:
$car = ['brand' => 'Audi', 'model' => 'A8'];
$engine = ['cylinder' => 6, 'displacement' => '3000cc'];
$merged = [...$car, ...$engine];
var_dump($merged);
Will result in:
[ Error ] Cannot unpack array with string keys
For an associative array you can just use merge.
$arr = array('item2', 'item3', 'item4');
$arr = array_merge(array('item1'), $arr)
Insert an item in the beginning of an associative array with string/custom key
<?php
$array = ['keyOne'=>'valueOne', 'keyTwo'=>'valueTwo'];
$array = array_reverse($array);
$array['newKey'] = 'newValue';
$array = array_reverse($array);
RESULT
[
'newKey' => 'newValue',
'keyOne' => 'valueOne',
'keyTwo' => 'valueTwo'
]
There are two solutions:
if you have array with keys that matter to you
$new = ['RLG' => array(1,2,3)];
$array = ['s' => array(2,3), 'l' => [], 'o' => [], 'e' => []];
$arrayWithNewAddedItem = array_merge($new, $array);
if you have an array without any keys.
array_unshift(array, value1);
Use array_unshift() to insert the first element in an array.
Use array_shift() to remove the first element of an array.
Or you can use temporary array and then delete the real one if you want to change it while in cycle:
$array = array(0 => 'a', 1 => 'b', 2 => 'c');
$temp_array = $array[1];
unset($array[1]);
array_unshift($array , $temp_array);
the output will be:
array(0 => 'b', 1 => 'a', 2 => 'c')
and when are doing it while in cycle, you should clean $temp_array after appending item to array.
I have an array which may contain numeric or associative keys, or both:
$x = array('a', 'b', 'c', 'foo' => 'bar', 'd', 'e');
print_r($x);
/*(
[0] => a
[1] => b
[2] => c
[foo] => bar
[3] => d
[4] => e
)*/
I want to be able to remove an item from the array, renumbering the non-associative keys to keep them sequential:
$x = remove($x, "c");
print_r($x);
/* desired output:
(
[0] => a
[1] => b
[foo] => bar
[2] => d
[3] => e
)*/
Finding the right element to remove is no issue, it's the keys that are the problem. unset doesn't renumber the keys, and array_splice works on an offset, rather than a key (ie: take $x from the first example, array_splice($x, 3, 1) would remove the "bar" element rather than the "d" element).
This should re-index the array while preserving string keys:
$x = array_merge($x);
You can fixet with next ELEGANT solution:
For example:
<?php
$array = array (
1 => 'A',
2 => 'B',
3 => 'C'
);
unset($array[2]);
/* $array is now:
Array (
1 => 'A',
3 => 'C'
);
As you can see, the index '2' is missing from the array.
*/
// SOLUTION:
$array = array_values($array);
/* $array is now:
Array (
0 => 'A',
1 => 'C'
);
As you can see, the index begins from zero.
*/
?>
I've come up with this - though I'm not sure if it's the best:
// given: $arr is the array
// $item is the item to remove
$key = array_search($item, $arr); // the key we need to remove
$arrKeys = array_keys($arr);
$keyPos = array_search($key, $arrKeys); // the offset of the item in the array
unset($arr[$key]);
array_splice($arrKeys, $keyPos, 1);
for ($i = $keyPos; $i < count($arrKeys); ++$i) {
if (is_int($arrKeys[$i])) --$arrKeys[$i]; // shift numeric keys back one
}
$arr = array_combine($arrKeys, $arr); // recombine the keys and values.
There's a few things I've left out, just for the sake of brevity. For example, you'd check if the array is associative, and also if the key you're removing is a string or not before using the above code.
Try array_diff() it may not order the new array correctly though
if not the following should work
You will need to iterate over it in the remove function.
function remove($x,$r){
$c = 0;
$a = array();
foreach ($x as $k=>$v){
if ($v != $r) {
if (is_int($k)) {
$a[$c] = $v;
$c++;
}
else {
$a[$k] = $v;
}
}
}
return $a;
}
DC
I don't think there is an elegant solution to this problem, you probably need to loop to the array and reorder the keys by yourself.