Php array get all values that are repeating - php

I have a Php array that have values of times as array values and timestamps as key array is like this:
array(
144454884=>"12:00am", 145454884=>"12:30am", 144474884=>"1:00am", 144454864=>"1:30am", 143354884=>"1:00am", 144654884=>"1:30am", 1444567584=>"2:00am "
);
Timestamp values in above example are not real I wrote an example they are useless anyway unless your timezone matches mine.
Problem:
I need to get "1:00am" and "1:30am" twice I can get repeating values 1 time as shown in answer here:
php return only duplicated entries from an array
I need both repeating values two times with both keys and values being repeated because I need to eliminate those timestamps from week time on my system because of daylight saving a time is repeating and I don't want to show 1:00am at all I just want to show this time as unavailable.

I am not 100% sure what you wanted but this is what I think you need.
Assuming your input array is called $a
$b = array_flip(array_flip($a));
$c = array_diff_key($a, $b);
$b will contain an array of unique values.
$c will contain the elements that were removed.
Results of $b and $c are as follows:
array(5) {
[144454884] = string(7) "12:00am"
[145454884] = string(7) "12:30am"
[143354884] = string(6) "1:00am"
[144654884] = string(6) "1:30am"
[1444567584] = string(7) "2:00am "
}
array(2) {
[144474884] = string(6) "1:00am"
[144454864] = string(6) "1:30am"
}

This code works :
<?php
$array_new = [];
$array_tmp = [];
$array = array(1=>'1233',2=>'12334',3 =>'Hello' ,4=>'hello', 5=>'U');
//loop trough all elements in array and for ever element create key
//For "world" key is "world"
//For "World" key is "world"
//For "WORLD" key is "world"
//So all this cases have same key and differenet representation eg. "world" => ["world","World","WORLD"]
foreach($array as $k => $v){
$index = strtolower($v);
$array_tmp[$index][] = $v;
}
//loop trough new array with new keys and if there are more than one element(> 1) for some key, all of his representations put in new array
foreach($array_tmp as $k => $v){
if(count($v) > 1){
foreach($v as $k2 => $v2){
$array_new[] = $v2;
}
}
}
echo '<pre>';
print_r($array_new);
echo '<pre>';

A possible solution keeping the key information (I will assign the intermediate results to their own variables otherwise it can be confusing to read)
$array = array(
143354883 => "1:00am",
144454884 => "12:00am",
145454884 => "12:30am",
144474884 => "1:00am",
144454864 => "1:30am",
143354884 => "1:00am",
144654884 => "1:30am",
1444567584 => "2:00am ",
0 => 4,
1 => 4,
2 => 4,
3 => "Test",
4 => "TEST",
5 => "test "
);
// Used this array_iunique function: http://stackoverflow.com/questions/2276349/case-insensitive-array-unique
function array_iunique($array) {
return array_intersect_key(
$array,
array_unique(array_map("StrToLower",$array))
);
}
$unique = array_iunique($array);
// Then get the difference by key, that will give you all the duplicate values:
$diff_key = array_diff_key($array, $unique);
// Now we have to find the values that are in the $diff_key and the $unique because we also want to have those:
$correspondingValues = array_uintersect($unique, $diff_key, "strcasecmp");
// Then we have to combine the $duplicate values with the $diff_key and preserve the keys:
$result = array_replace($correspondingValues, $diff_key);
var_dump($result);
Will result in:
array(10) {
[143354883]=>
string(6) "1:00am"
[144454864]=>
string(6) "1:30am"
[0]=>
int(4)
[3]=>
string(4) "Test"
[144474884]=>
string(6) "1:00am"
[143354884]=>
string(6) "1:00am"
[144654884]=>
string(6) "1:30am"
[1]=>
int(4)
[2]=>
int(4)
[4]=>
string(4) "TEST"
}

Related

Generate multidimensional array based on given array

I have an array say,
$arr = ["x", "y", "z"];
What I want to achieve is create another array based on given array such as
$arr1["x" =>["y" => ["z"]]] = "some value";
Any idea to achieve this? Thanks in advance.
Edited:
'some value' is just a dummy data. What I'm trying to achieve is the multidimensional structure.
You can recursively build an array, taking and removing the first element of an array on each call :
function buildArray($arr, $someValue)
{
if (count($arr) == 0)
return $someValue;
// the key is the first element of the array,
// removed and returned at the same time using array_shift()
return [ array_shift($arr) => buildArray($arr, $someValue) ];
}
$arr = ["x", "y", "z"];
$arr1 = buildArray($arr, "some value");
var_dump($arr1);
echo "------------------------" . PHP_EOL;
// note that $arr is preserved
var_dump($arr);
This outputs :
array(1) {
["x"]=>
array(1) {
["y"]=>
array(1) {
["z"]=>
string(10) "some value"
}
}
}
------------------------
array(3) {
[0]=>
string(1) "x"
[1]=>
string(1) "y"
[2]=>
string(1) "z"
}
$keys = array('key1', 'key2', 'key3');
$value = 'some value';
$md = array();
$md[$keys[count($keys)-1]] = $value;
for($i=count($keys)-2; $i>-1; $i--)
{
$md[$keys[$i]] = $md;
unset($md[$keys[$i+1]]);
}
print_r($md);
You need to create recursive function:
function rec_arr($ar, $val){
$res = [];
if(is_array($ar) && count($ar)>0){
$tmp = $ar[0]; // catching the first value
unset($ar[0]); // unset first value from given array
sort($ar); // makes indexes as 0,1,...
$res[$tmp] = rec_arr($ar, $val); // recursion
} else {
return $val; // passing value to the last element
}
return $res;
}
Demo
Outputs:
Array
(
[x] => Array
(
[y] => Array
(
[z] => some value
)
)
)

PHP alter array with array_search and array_column

I have an array ($myArray) which I want to alter:
array(2) {
[0]=>
array(2) {
[0]=>
string(3) "100"
[1]=>
string(9) "fancyLink"
}
[1]=>
array(2) {
[0]=>
string(3) "200"
[1]=>
string(10) "fanyLink2"
}
}
I have two POST arrays which have the following structure.
First array $number:
array(2) {
[0]=>
string(3) "100"
[1]=>
string(3) "200"
}
and the second array $links:
array(2) {
[0]=>
string(12) "newFancyLink"
[1]=>
string(13) "newFancyLink2"
}
To alter the $myArray in order to replace one or more links according to the $number-value I wanted to use the following line
for($i = 0; $i < 2; $i++)
{
$myArray[array_search($number[$i], array_column($myArray, "0"))][1] = $links[$i];
}
But this does not work, it sets both links of 100 and 200 to the same value (the second link)
I wrote this code which works, but I would like to use the other line instead or at least compare the perfomance of it
for($i = 0; $i < 2; $i++)
{
for($j = 0; $j < 2; $j++)
{
if($myArray[$j][0] == $number[$i])
{
$myArray[$j][1] = $links[$i];
}
}
}
Using the $number-value as a key would make this a lot easier but this is not an option for me.
EDIT after Solving
In case anybody wants to know, both versions are alost identical fast. 10000 runs each result in this runtime:
0.10158801078796
0.10160994529724
Perhaps array_column($myArray, "0") should be array_column($myArray, 0) instead (since it is not an associative array)? That way it seems to work for me.
From the PHP-manual
array array_column ( array $input , mixed $column_key [, mixed $index_key = null ] )
column_key
The column of values to return. This value may be an integer key of the column you wish to retrieve, or it may be a string key name for an associative array or property name. It may also be NULL to return complete arrays or objects (this is useful together with index_key to reindex the array).
The solution using array_map and array_walk functions:
$numLinks = array_map(null, $number, $links);
// you may also iterate via a regular 'foreach' loop
array_walk($myArray, function(&$v, $k) use($numLinks){
if ($v[0] == $numLinks[$k][0]) $v[1] = $numLinks[$k][1];
});
print_r($myArray);
The output:
Array
(
[0] => Array
(
[0] => 100
[1] => newFancyLink
)
[1] => Array
(
[0] => 200
[1] => newFancyLink2
)
)

Slicing two values from array and adding to new array in for loop

I am having issues with a php loop.
Perhaps there is a better way to do this. Currently my post is returning
array(4) {
[1]=> string(2) "on"
["1-qty"]=> string(1) "1"
[5]=> string(2) "on"
["5-qty"]=> string(1) "9"
}
I am trying to make a new array of 2 arrays such as the following
array(2) {
array(2) {
[category]=> string(2) "1"
["qty"]=> string(1) "1"
}
array(2) {
[category]=> string(2) "5"
["qty"]=> string(1) "9"
}
}
I have tried about every foreach and for loop that I can manage to put together. The main problem being the first value I need is the key not the value of the first array. Then I need to take the first two arrays from the main array and add to a new array with the first array key being the new value of the first key category in the array, and the value of the second array being the value of the new key qty in the array, and repeat by groups of 2 foreach set that is in the post variable
Current loop (not working)
$data = $this -> input -> post();
$dCount = count($data);
$newCount = $dCount / 2;
$fin = array();
for ($i = 0; $i <= $newCount; $i++) {
$vals = array_slice($data, 0, $i + 1, true);
$qty = array_slice($vals, 0, $i , true);
$key = current(array_keys($qty));
$final = array('category' => $key, 'qty' => $qty[$key . '-qty']);
$fin[] = $final;
}
Try this way:
$source_arr = array(1 => "on", "1-qty" => 1, 5 => "on", "5-qty" => "9");
$result_arr = array();
foreach ($source_arr as $key => $value) {
if ($value == "on" && isset($source_arr[$key . "-qty"])) {
$result_arr[] = array(
'category' => $key,
'qty' => $source_arr[$key . "-qty"]
);
}
}

Move some items to the end of the array if they fulfill a specific condition

I have an array of paths that I would like to sort ...
Array
(
/something/foo1
/something/special/foo2
/something/foo3
/something/special/foo4
/something/foo5
/something/special/foo6
)
... so that all paths that contain /special/ end up at the end of the array like this:
Array
(
/something/foo1
/something/foo3
/something/foo5
/something/special/foo2
/something/special/foo4
/something/special/foo6
)
The original sort order of paths must remain the same (so 1,2,3,4,5,6 => 1,3,5,2,4,6). Is there an elegant way to do this? Can this be implemented by using the usort function?
In your specific example, you can simply use asort($array);
But that is assuming foo is always foo.
Output:
array(6) {
[0]=>
string(15) "/something/foo1"
[2]=>
string(15) "/something/foo3"
[4]=>
string(15) "/something/foo5"
[1]=>
string(23) "/something/special/foo2"
[3]=>
string(23) "/something/special/foo4"
[5]=>
string(23) "/something/special/foo6"
}
If that's not the case, let me know and I'll do something else
... here is new method ref comment:
$array = array(
'/something/zoo',
'/something/special/foo',
'/something/loo',
'/something/special/goo',
'/something/boo',
'/something/special/poo'
);
uasort($array, function($a, $b) {
$specialInA = strpos($a, '/special/') !== false;
$specialInB = strpos($b, '/special/') !== false;
if ($specialInA > $specialInB) {
return 1;
}
if ($specialInB > $specialInA) {
return -1;
}
return $a > $b;
});
Output:
array(6) {
[4]=>
string(14) "/something/boo"
[2]=>
string(14) "/something/loo"
[0]=>
string(14) "/something/zoo"
[1]=>
string(22) "/something/special/foo"
[3]=>
string(22) "/something/special/goo"
[5]=>
string(22) "/something/special/poo"
}
Can probably be written better but should work
you can use unset and append [], like so
$x = array(1,2,3);
$x[] = $x[1];
unset($x[1]);
print_r($x);
Array
(
[0] => 1
[2] => 3
[3] => 2
)
You can thus loop over the array, test each element, and flip to the end the ones that contain the pattern.
$len = count($a);
for ($i=0; $i<$len; $i++) {
if (...) {
$a[] = $a[i];
unset($a[i]);
}
}
Edit: php's arrays are lists, hashes and arrays simultaneously. It is possible to move an element to the end while retaining its index! For example
$a = array(1,2,3);
$t = $a[1];
unset($a[1]);
$a[1] = $t;
print_r($a);
Array
(
[0] => 1
[2] => 3
[1] => 2
)

Convert array in array to string

I wonder if there's easy way to convert array which is in another array to string and keep it in that array ? The array which is inside array always consists of only 1 key. This is array that I have now:
array(6) {
["miestas"]=>
string(2) "CC"
["checkbox"]=>
array(1) {
[0]=>
string(1) "1"
}
["kiekis"]=>
string(5) "Three"
}
And this is the result what I want to get:
array(6) {
["miestas"]=>
string(2) "CC"
["checkbox"]=>
string(1) "1"
["kiekis"]=>
string(5) "Three"
}
Read this: http://php.net/array
Use this: $array['checkbox'] = $array['checkbox'][0];
You can type cast the value
$data['checkbox'] = (string) $data['checkbox'];
array_replace
$replacement = array('checkbox' => 1);
$outputYouWant = array_replace($yourArray, $replacement);
print_r($outputYouWant);
Loops through the input array and checks if value is an array using is_array function. Pushes value array's value at index zero if an array otherwise pushes value to the result array.
$input = array('miestas' => 'CC', 'checkbox' => array("1"), 'kiekis' => 'Three');
$result = array();
foreach($input as $key=>$value) {
$result[$key] = is_array($value) ? $value[0] : $value;
}
// var_dump($result);

Categories