PHP shuffle numerically indexed object array preserve key-value - php

I have array like this.
A=array();
A[0]=>name = "John";
A[0]=>lastname = "Blabla";
A[0]=>genre = "Male";
A[1]=>name = "Cheryl";
A[1]=>lastname = "Blabla";
A[1]=>genre = "Female";
I want to shuffle this array with preserving key-value pairs and without mixing every key. So basicly A[0] will be A[1](there are more than only 2 index just example it should be random) with all of child keys values etc.
How can i do this? Thanks

You can loop through the array and then randomly exchange the values in it.
for($x=0;$x<count($array);$x++){
$temp=$array[$x];
$index=rand(0,count($array)-1);
$array[x]=$array[$index];
$array[$index]=$temp;
}
Working example below.
<?php
$array=array();
$array[0]['name'] = "John";
$array[0]['lastname'] = "Blabla";
$array[0]['genre'] = "Male";
$array[1]['name'] = "Cheryl";
$array[1]['lastname'] = "Blabla";
$array[1]['genre'] = "Female";
$array[2]['name'] = "Amy";
$array[2]['lastname'] = "Blabla";
$array[2]['genre'] = "Female";
$array[3]['name'] = "Adam";
$array[3]['lastname'] = "Blabla";
$array[3]['genre'] = "Female";
$array[4]['name'] = "Hitan";
$array[4]['lastname'] = "Blabla";
$array[4]['genre'] = "Male";
$array[5]['name'] = "Mary";
$array[5]['lastname'] = "Blabla";
$array[5]['genre'] = "Female";
for($x=0;$x<count($array);$x++){
$temp=$array[$x];
$index=rand(0,count($array)-1);
$array[$x]=$array[$index];
$array[$index]=$temp;
}
var_dump($array);

Just randomize the index of the array, no need to care about the specific field of object stored as array element.
public function randomObj(A)
{
$index = rand(0, 1);
return A[$index];
}
Add here as an extra explanation: shuffle means you swap certain amount of objects(which change the index of the object as an element in the array), while randomize means you get an object randomly(no need to change the index of object, but when you want to get one, it returns a random object).

This function returns same array with shuffled iteration order:
function kshuffle($a) {
$k = array_keys($a);
shuffle($k);
$res = [];
foreach($k as $index) $res[$index] = $a[$index];
return $res;
}
print_r(kshuffle(['a', 'b', 'c', 'd', 'e', 'f', 'g']));
Array
(
[4] => e
[1] => b
[3] => d
[0] => a
[6] => g
[5] => f
[2] => c
)
So, it will produce shuffled sequence, while we iterate result with foreach.
It also will generate hashtable/object if you want to json_encode result: {"1": "b", "0": "a"}. But be careful, if random returns unshuffled sequence(there is always probability for this event) it will plain array: ['a', 'b'] without JSON_FORCE_OBJECT flag.

Related

Pushing an Array element into an existing multidimensional array in codeigniter

I have a query in codeigniter like this
$query_tutors = $this->db->get_where("tutor_info", array('tutor_id' => $tutor_id));
I have also other array elements that I want to pass in the query which depends on some conditions.
So how do I push other multidimensional array elements to the existing array so I can pass the variable as a whole in the query?
array_push is not working in this case.
$array = array();
$array = array("tutor_id" => $tutor_id);
$array = array("online" => $online); // want to merge this to the 1st array.
$query_tutors = $this->db->get_where("tutor_info", $array);
First you're doing it wrong.
$array = array();
$array = array("tutor_id" => $tutor_id);
You're recreating the array again, which will delete it from the memory. Either you have to use
$array['tutor_id'] = $tutor_id;
$array["online"] = $online;
or
$array = array('tutor_id' => $tutor_id, 'online' => $online);
or if you want to merge two arrays
$array = array_merge(array('tutor_id' => $tutor_id), array('tutor_id' => $tutor_id));
Your initial code
$array = [];
$array = ["tutor_id" => $tutor_id];
Now, if you want to add conditional merge, simply follow,
if($condition)
{
$array = array_merge($array, ["online" => $online]);
}
If $condition == true You final array will be,
$array = ['tutor_id' => $tutor_id, 'online' => $online];
You are almost there, just need to read a little bit more about associative arrays.
Solution:
$array = array();
$array["tutor_id"] = $tutor_id;
$array["online"] = $online;
$query_tutors = $this->db->get_where("tutor_info", $array);
This way your $array will have all indexes which you want.
You can do something like this:
$array = array();
if (!empty($tutor_id))
{
$array["tutor_id"] = $tutor_id;
}
if (!empty($online))
{
$array["online"] = $online;
}
$query_tutors = $this->db->get_where("tutor_info", $array);

How to prevent duplicate keys from array_push

I have 2 2D arrays, how can i get the unique keys and only push those? For example:
$array = json_decode('[{"7654321":1368356071},{"1234567":1368356071}]',true);
$array2 = array(array(1234567 => time()), array(7654321 => time()), array(2345678 => time()));
//array_push($array, $array2[2]);
-- How can I dynamically get the unique key like $array2[2] in this example?
why not to use array_unique() function in php? http://php.net/manual/ru/function.array-unique.php
You mean, you would like to push into another array (let's say in $keys_unique) whatever key(s) that are present only in one of the first two arrays, but not present in both of them?
Try this:
$arrays_mixed = array( //your $array and $array2; you can put as many arrays as you want here
json_decode('[{"7654321":1368356071},{"1234567":1368356071}]',true)
,array(array(1234567 => time()), array(7654321 => time()), array(2345678 => time()))
);
//begin getting all keys
$arrays_keys = array(); //will hold all keys from arrays_mixed
$keys_unique = array(); //will hold all unique keys out of arrays_key
for($x=0;$x<count($arrays_mixed);$x++){
$arrays_keys[$x] = array(); //prepares a "keys holder"
$toflatten = $arrays_mixed[$x];
$c1 = 0;
do{
$arrmixed = array();
$arrclean = array();
foreach($toflatten as $a){
$arrmixed = $this->keys_finder($a,1);
$arrclean[$c1] = $this->keys_finder($a,2);
$c1++;
}
$toflatten = $arrmixed;
}while(is_array($toflatten));
for($c2=0;$c2<$c1;$c2++)
foreach($arrclean[$c2] as $ac)
array_push($arrays_keys[$x],$ac);
}//end geting all keys
//begin finding unique keys
foreach($arrays_keys as $ak)
foreach($ak as $add)
$keys_unique = $this->unique_inserter($arrays_keys,$keys_unique,$add);
//end finding unique keys
Here are the functions you need
function unique_inserter($arrays_keys,$keys_unique,$add){
$detector = 0; //detects how many arrays contain a value
foreach($arrays_keys as $ak)
if(in_array($add,$ak))
$detector++;
if($detector<2) //if value is found in one array only
array_push($keys_unique,$add);
return $keys_unique;
}
function keys_finder($array,$return){
$arrmixed = array();
$arrclean = array();
foreach($array as $key=>$a)
if(is_array($a))
foreach($a as $aa)
array_push($arrmixed,$aa);
else
array_push($arrclean,$key);
switch($return){
case 1:
return (count($arrmixed)==0)?'':$arrmixed;
break;
case 2:
return $arrclean;
break;
}
}
I have tested this code and it works on my side. Hope it helps.

PHP in_array isn't finding a value that is there

I have an array called $friend_array. When I print_r($friend_array) it looks like this:
Array ( [0] => 3,2,5 )
I also have a variable called $uid that is being pulled from the url.
On the page I'm testing, $uid has a value of 3 so it is in the array.
However, the following is saying that it isn't there:
if(in_array($uid, $friend_array)){
$is_friend = true;
}else{
$is_friend = false;
This always returns false. I echo the $uid and it is 3. I print the array and 3 is there.
What am I doing wrong? Any help would be greatly appreciated!
Output of
Array ( [0] => 3,2,5 )
... would be produced if the array was created by something like this:
$friend_array = array();
array_push($friend_array, '3,2,5');
print_r($friend_array);
Based on your question, I don't think this is what you meant to do.
If you want to add three values into the first three indexes of the array, do the following:
$friend_array = array();
array_push($friend_array, '3');
array_push($friend_array, '2');
array_push($friend_array, '5');
or, as a shorthand for array_push():
$friend_array = array();
$friend_array[] = '3';
$friend_array[] = '2';
$friend_array[] = '5';
Array ( [0] => 3,2,5 ) means that the array element 0 is a string 3,2,5, so, before you do an is_array check for the $uid so you have to first break that string into an array using , as a separator and then check for$uid:
// $friend_array contains as its first element a string that
// you want to make into the "real" friend array:
$friend_array = explode(',', $friend_array[0]);
if(in_array($uid, $friend_array)){
$is_friend = true;
}else{
$is_friend = false;
}
Working example
Looks like your $friend_array is setup wrong. Each value of 3, 2, and 5 needs its own key in the array for in_array to work.
Example:
$friend_array[] = 3;
$friend_array[] = 2;
$firned_array[] = 5;
Your above if statement will then work correctly.

PHP - Automatically creating a multi-dimensional array

So here's the input:
$in['a--b--c--d'] = 'value';
And the desired output:
$out['a']['b']['c']['d'] = 'value';
Any ideas? I've tried the following code without any luck...
$in['a--b--c--d'] = 'value';
// $str = "a']['b']['c']['d";
$str = implode("']['", explode('--', key($in)));
${"out['$str']"} = 'value';
This seems like a prime candidate for recursion.
The basic approach goes something like:
create an array of keys
create an array for each key
when there are no more keys, return the value (instead of an array)
The recursion below does precisely this, during each call a new array is created, the first key in the list is assigned as the key for a new value. During the next step, if there are keys left, the procedure repeats, but when no keys are left, we simply return the value.
$keys = explode('--', key($in));
function arr_to_keys($keys, $val){
if(count($keys) == 0){
return $val;
}
return array($keys[0] => arr_to_keys(array_slice($keys,1), $val));
}
$out = arr_to_keys($keys, $in[key($in)]);
For your example the code above would evaluate as something equivalent to this (but will work for the general case of any number of -- separated items):
$out = array($keys[0] => array($keys[1] => array($keys[2] => array($keys[3] => 'value'))));
Or in more definitive terms it constructs the following:
$out = array('a' => array('b' => array('c' => array('d' => 'value'))));
Which allows you to access each sub-array through the indexes you wanted.
$temp = &$out = array();
$keys = explode('--', 'a--b--c--d');
foreach ($keys as $key) {
$temp[$key] = array();
$temp = &$temp[$key];
}
$temp = 'value';
echo $out['a']['b']['c']['d']; // this will print 'value'
In the code above I create an array for each key and use $temp to reference the last created array. When I run out of keys, I replace the last array with the actual value.
Note that $temp is a REFERENCE to the last created, most nested array.

Whats the most elegant way to rearrange an associative array?

Suppose you have an associative array
$hash['Fruit'] = 'Apple';
$hash['Name'] = 'Jeff';
$hash['Car'] = 'Ford';
and you cannot change the order in which these variables are created. So Car is always added to the array after Name, etc. What's the prettiest way to add/move Car to the beginning of the associative array instead of the end (default)?
$hash = array('Car' => 'Ford') + $hash;
ksort() ?
But why would you care about the array's internal order?
array_reverse($hash, true);
This is not a very direct solution but one that is:
$value = end($hash);
$hash = array(key($hash) => $value) + $hash;
Another trick is -
$new_items = array('Car' => 'Ford');
$hash = array_merge($new_items, $hash);
You can re arrange the new array keys also. Suppose car first then another field (say Id) then array remain so....
$new_items = array('Car' => 'Ford','Id'=>'New Id');
$hash = array_merge($new_items, $hash);
The array will become like
$hash['Car'] = 'Ford';
$hash['Id'] = 'New Id';
$hash['Fruit'] = 'Apple';
$hash['Name'] = 'Jeff';

Categories