How to not add duplicates to array in O(1) time - php

I have an INT array. I want to add a number to the array. However, I don't want to add the number if the number already exists. I know I can use array_unique() but the time complexity of that is not O(1). How can I do this in O(1) time complexity. I know I can make the numbers the keys and have empty values and search use isset() to check if the number exists. Is there any other way?
$arr = [1,2,3,4];
$arr = add_to_array($arr, 4); // Should not add arr
$arr = add_to_array($arr, 7); // Should add arr
function add_to_array($arr, $num) {
if(in_array($num, $arr)) {
$arr[] = $num;
}
return $arr;
}

use in_array()==false then add to array as below code
$arr = [1,2,3,4];
$arr = add_to_array($arr, 4); // Should not add arr
$arr = add_to_array($arr, 7); // Should add arr
function add_to_array($arr, $num) {
if(in_array($num, $arr) == false) {
array_push($arr, $num);
}
return $arr;
}
Your output will be :
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 7 )

Related

How to get the factorial value of each number in an array?

I am trying to get an factorial value of each item in array by using this method but this outputs only one value
can any body help me finding where i am doing wrong?
function mathh($arr, $fn){
for($i = 1; $i < sizeof($arr); $i++){
$arr2 = [];
$arr2[$i] = $fn($arr[$i]);
}
return $arr2;
}
$userDefined = function($value){
$x = 1;
return $x = $value * $x;
};
$arr = [1,2,3,4,5];
$newArray = mathh($arr, $userDefined);
print_r($newArray);
You're going to need a little recursion so in order to do that you need to pass the lambda function into itself by reference:
function mathh($arr, $fn){
$arr2 = []; // moved the array formation out of the for loop so it doesn't get overwritten
for($i = 0; $i < sizeof($arr); $i++){ // starting $i at 0
$arr2[$i] = $fn($arr[$i]);
}
return $arr2;
}
$userDefined = function($value) use (&$userDefined){ // note the reference to the lambda function $userDefined
if(1 == $value) {
return 1;
} else {
return $value * $userDefined($value - 1); // here is the recursion which performs the factorial math
}
};
$arr = [1,2,3,4,5];
$newArray = mathh($arr, $userDefined);
print_r($newArray);
The output:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 24
[4] => 120
)
I wanted to expand on this some since you're essentially (in this case) creating an array map. This could be handy if you're doing additional calculations in your function mathh() but if all you want to do is use the lambda function to create a new array with a range you could do this (utilizing the same lambda we've already created):
$mapped_to_lambda = array_map($userDefined, range(1, 5));
print_r($mapped_to_lambda);
You will get the same output, because the range (1,5) of the mapped array is the same as your original array:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 24
[4] => 120
)

Remove duplicated values completely deleted from array in php

I want to remove the values from array which are same.
For example:
This is the array.
Array ( [0] => 1 [1] => 63 [2] => 1 )
is there any function or something in core php which return me only the value which is not duplicate i.e value with index number 1 and delete index 0 and 2, I want the result
Array ( [1] => 63)
Is there any way?
You can use array_filter() and array_count_values() to check the count is not greater then 1.
<?php
$data = [1, 63, 1];
$data = array_filter($data, function ($value) use ($data) {
return !(array_count_values($data)[$value] > 1);
});
print_r($data);
https://3v4l.org/uIVLN
Result:
Array
(
[1] => 63
)
Will also work fine with multiple dupes: https://3v4l.org/eJSTY
One option is to use array_count_values to count the values. Loop and push only the 1 values
$arr = array(1,63,1);
$arrKey = array_flip( $arr ); //Store the key
$result = array();
foreach( array_count_values($arr) as $k => $v ) {
if ( $v === 1 ) $result[ $arrKey[$k] ] = $k;
}
echo "<pre>";
print_r( $result );
echo "</pre>";
This will result to:
Array
(
[1] => 63
)
Doc: array_count_values
I believe that the best solution is the following:
function removeDuplicates(array $initialArray) : array
{
// Remove duplicate values from an array
$uniqueValues = array_unique($initialArray);
// Computes the difference of arrays with additional index check
$duplicateValues = array_diff_assoc($initialArray, $uniqueValues);
// Removed any values in both arrays
return array_diff($uniqueValues, $duplicateValues);
}
This solution utilises the following functions in PHP:
array_unique
array_diff_asoc
array_diff
You can use array_keys() with a search value as the second parameter to see how many times a value exists.
$array = [1, 63, 1, 12, 64, 12];
$new = [];
foreach ($array as $value) {
// Get all keys that have this value. If there's only one, save it.
if (count(array_keys($array, $value)) == 1) {
$new[] = $value;
}
}
Demo: https://3v4l.org/G1DCg
I don't know the performance of this compared to the other answers. I leave the profiling to someone else.

How to use a returned PHP array inside an array itself? [duplicate]

This question already has answers here:
How to Flatten a Multidimensional Array?
(31 answers)
Closed 6 months ago.
I would like to create a PHP array, where some of the elements are to be replaced by elements of an array returned by a function. As example, I would like to create the following array:
$aArray = array(
0x01,
0x10,
foo(1234),
0x03,
foo(445),
...
)
Here, foo is a function returning a simple PHP array. What I get is, of course, something like
(
[0] => 1
[1] => 16
[2] => Array
(
[1] => 2
[2] => 4
)
[3] => 03
[4] => Array
....
But what I actually want to do is to include the returned values from the function directly into the array, to create something like:
(
[0] => 1
[1] => 16
[2] => 2
[3] => 4
[4] => 03
[5] => 3
....
Is this possible to do in a simple way, without having to construct the array with array_merge?
P.S: The above example is not a working example, just showing what I want to do. The content of the function foo is also irrelevant.
This is the closest thing that I can do to match your need
$aArray = array_flat(
0x01,
0x10,
foo(1234),
0x03,
foo(445)
);
And here is code for array_flat.
function array_flat()
{
$array = func_get_args()
$result = array();
foreach ($array as $value) {
is_array($value) || $value = array($value);
foreach ($value as $dvalue) {
$result[] = $dvalue;
}
}
return $result;
}
You can pass this array to the function by reference and do with it what you will inside the function.
public function test(&$arr) {
$arr[] = 1234;
}
$arr = array(1, 2, 3);
test($arr);
print_r($arr); // array(1, 2, 3, 1234);
Or you can drop the references and return the array from the function normally:
public function test($arr) {
$arr[] = 1234;
return $arr;
}
$arr = array(1, 2, 3);
$arr = test($arr);
print_r($arr); // array(1, 2, 3, 1234);
You'll need to array_merge the separate arrays:
$aArray = array_merge(array(0x01, 0x10), foo(1234), array(0x03), foo(445));
If you need that in the array, you either need to manage that when adding or afterwards.
If you want to do this step by step as the data becomes available, you can push to the array each time. Here is an example with two anonymous functions that are pushing into your array each time invoked:
$pushArray = function(&$array) {
return function($item) use (&$array) {
is_array($item) || $item = array($item);
foreach($item as $value) {
$array[] = $value;
}
};
}
$array = array();
$push = $pushArray($array);
$push(0x01);
$push(0x10);
$push(foo(1234));
...
If you want to do it afterewards you can do this for example with casting and merging:
function arrayval($mixed) {
settype($mixed, 'array');
return $mixed;
}
$flat = call_user_func_array('array_merge', array_map('arrayval', $array));
Another one is by reducing the array later on which is properly more easy to understand:
$flat = array_reduce($array, function($result, $item) {
return array_merge((array) $result, (array) $item);
});
For everything afterwards, more Q&A on this website already exists:
How to “flatten” a multi-dimensional array to simple one in PHP?

PHP::How merge 2 arrays when array 1 values will be in even places and array 2 will be in odd places? [duplicate]

This question already has answers here:
Transpose and flatten two-dimensional indexed array where rows may not be of equal length
(4 answers)
Closed 10 months ago.
How can I merge two arrays when array 1 values will be in even places and array 2 will be in odd places?
Example:
$arr1=array(11, 34,30);
$arr2=array(12, 666);
$output=array(11, 12, 34, 666,30);
This will work correctly no matter the length of the two arrays, or their keys (it does not index into them):
$result = array();
while(!empty($arr1) || !empty($arr2)) {
if(!empty($arr1)) {
$result[] = array_shift($arr1);
}
if(!empty($arr2)) {
$result[] = array_shift($arr2);
}
}
Edit: My original answer had a bug; fixed that.
try this
$arr1=array(11,34,30,35);
$arr2=array(12,666,23);
$odd= array_combine(range(0,2*count($arr1)-1,2), $arr1);
$even = array_combine(range(1,2*count($arr2)-1,2), $arr2);
$output=$odd+$even;
ksort($output);
echo "<pre>";
print_r($output);
returns
Array
(
[0] => 11
[1] => 12
[2] => 34
[3] => 666
[4] => 30
[5] => 23
[6] => 35
)
Assuming $arr1 and $arr2 are simple enumerated arrays of equal size, or where $arr2 has only one element less that $arr1.
$arr1 = array(11, 34);
$arr2 = array(12, 666);
$output = array();
foreach($arr1 as $key => $value) {
$output[] = $value;
if (isset($arr2[$key])) {
$output[] = $arr2[$key];
}
}
Go through array with more items, use loop index to access both arrays and combine them into resulting one as required...
$longer = (count($arr1) > count($arr2) ? $arr1 : $arr2);
$result = array();
for ($i = 0; $i < count($longer); $i++) {
$result[] = $arr1[i];
if ($arr2[i]) {
$result[] = $arr2[i];
} else {
$result[] = 0; // no item in arr2 for given index
}
}

Filter array - odd even

How can a filter out the array entries with an odd or even index number?
Array
(
[0] => string1
[1] => string2
[2] => string3
[3] => string4
)
Like, i want it remove the [0] and [2] entries from the array.
Or say i have 0,1,2,3,4,5,6,7,8,9 - i would need to remove 0,2,4,6,8.
foreach($arr as $key => $value) if($key&1) unset($arr[$key]);
The above removes odd number positions from the array, to remove even number positions, use the following:
Instead if($key&1) you can use if(!($key&1))
Here's a "hax" solution:
Use array_filter in combination with an "isodd" function.
array_filter seems only to work on values, so you can first array_flip and then use array_filter.
array_flip(array_filter(array_flip($data), create_function('$a','return $a%2;')))
You could also use SPL FilterIterator like this:
class IndexFilter extends FilterIterator {
public function __construct (array $data) {
parent::__construct(new ArrayIterator($data));
}
public function accept () {
# return even keys only
return !($this->key() % 2);
}
}
$arr = array('string1', 'string2', 'string3', 'string4');
$filtered = array();
foreach (new IndexFilter($arr) as $key => $value) {
$filtered[$key] = $value;
}
print_r($filtered);
<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
function even($var)
{
// returns whether the input integer is even
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>
Odd :
Array
(
[a] => 1
[c] => 3
[e] => 5
)
Even:
Array
(
[0] => 6
[2] => 8
[4] => 10
[6] => 12
)
I'd do it like this...
for($i = 0; $i < count($array); $i++)
{
if($i % 2) // OR if(!($i % 2))
{
unset($array[$i]);
}
}
<?php
$array = array(0, 3, 5, 7, 20, 10, 99,21, 14, 23, 46);
for ($i = 0; $i < count($array); $i++)
{
if ($array[$i]%2 !=0)
echo $array[$i]."<br>";
}
?>
$array = array(0 => 'string1', 1 => 'string2', 2 => 'string3', 3 => 'string4');
// Removes elements of even-numbered keys
$test1 = array_filter($array, function($key) {
return ($key & 1);
}, ARRAY_FILTER_USE_KEY);
// Removes elements of odd-numbered-keys
$test2 = array_filter($array, function($key) {
return !($key & 1);
}, ARRAY_FILTER_USE_KEY);
This answer is a bit of an improvement over this answer. You can use anonymous functions instead of create_function. Also, array_filter takes an optional flag parameter that lets you specify that the callback function takes the key as its only argument. So you don't need to use array_flip to get an array of keys.

Categories