I have a multi-dimensional array and from where i want to choose 11 different words. Each word from different array index.
Here is the array link: My multi-dimensional array
array (
'w' =>
array (
0 => 'walls',
1 => 'well',
2 => 'why',
),
'e' =>
array (
0 => 'end',
),
'a' =>
array (
0 => 'advantage',
1 => 'afford',
2 => 'affronting',
3 => 'again',
4 => 'agreeable',
5 => 'ask',
6 => 'at',
),
'c' =>
array (
0 => 'children',
1 => 'civil',
2 => 'continual',
)
);
My Desire Output:
From w => well
From e => end
From a => again
and so on.
Output like: array(well, end, again, ...) as array.
Use the following code:
$f = array_keys($result); // grouping the indices, namely, the characters
$a = "";
for($c=0;$c<count($f);$c++){
$a .= $f[$c];
} // grouping the indices stored in array $f to a string, $a
$words = array();
for($c=0;$c<11;$c++){
$random = $a[rand(0,strlen($a)-1)];
$k = $result[$random];
// $k stores the array of the character index, stored in $result
$random2 = rand(0,count($k)-1);
$words[$c] = $k[$random2];
// choose a word from a given character array
$a = preg_replace("/".$random."/","",$a);
// remove the character from $a to prevent picking words which start with the same character
}
print_r($words);
I've tested and it was proved working
https://3v4l.org/qi1VP
You can achieve this usin array_rand() function :
PHP
$words = [];
$limit = 3; //Replace this with your limit, 11
$count = 0;
shuffle($array);
foreach($array as $key => $value) {
$words[] = $value[array_rand($value)];
$count++;
if ($limit == $count) {
break;
}
}
EvalIn
Check Online, and let me know.
using shuffle and array_slice you can get what you want.
A shuffle function makes your array random, and array slice slice 11 sub array from it.
Array slice takes 3 argument, first one is the array, second one is the offset from where you want to start and last one how much you need to cut.
$words = array();
shuffle($result);
$res = array_slice($result, 0, 11);
foreach($res as $key => $value){
shuffle($value);
$words[] = $value[0];
}
print_r($words);
Related
I'm probably [super]overthinking this. I'm trying to analyze an array with values like [1,9], [4,6] [5,5], [6,4], [9,1] and duplicate digits (I'm having a super brain fart and can't even remember the term for numbers like this) remove (the last two) so that only [1,9], [4,6] [5,5] are printed.
I was thinking that turning this array into a string and using preg_match, but I'm pretty sure this wouldn't work even if I had the correct regex.
If you have an array of pairs like this:
$x = array(
array(1,9),
array(4,6),
array(5,5),
array(6,4),
array(9,1)
);
Here is one way to get the unique pairs:
foreach ($x as $pair) {
sort($pair);
$unique_pairs[implode(',', $pair)] = $pair;
}
This uses string representations of each sorted pair as keys in a new array, so the result will have distinct values by definition.
As far as the printing them out part of your question, once you have the unique values you can loop over them and print them out in whichever format you like, for example:
foreach ($unique_pairs as $pair) { vprintf("[%d,%d]<br>", $pair); }
It looks like elements are distributed symmetrically.
We can cut the array in two halves and get only the first half with array_slice():
$array = array(
array(1,9),
array(4,6),
array(5,5),
array(6,4),
array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));
Result:
Array(
[0] => Array(
[0] => 1
[1] => 9
)
[1] => Array(
[0] => 4
[1] => 6
)
[2] => Array(
[0] => 5
[1] => 5
)
)
Demo at Codepad.
ceil() is used to round the number up to the next highest integer if there is an even number of items in the array. Example: if there is 3 items in the array, 5 / 2 will return 2.5, we want 3 items so we use ceil(2.5) which gives 3.
Example with 3 items:
$array = array(
array(1,9),
array(5,5),
array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));
Result:
Array(
[0] => Array(
[0] => 1
[1] => 9
)
[1] => Array(
[0] => 5
[1] => 5
)
)
Example with 4 items:
$array = array(
array(1,9),
array(7,7),
array(7,7),
array(9,1),
);
print_r(array_slice($array, 0, ceil(count($array) / 2)));
Result:
Array(
[0] => Array(
[0] => 1
[1] => 9
)
[1] => Array(
[0] => 7
[1] => 7
)
)
If I'm correct in understanding what you are trying to do, you want to remove the final 2 elements from the array?
There is a function in PHP called array_pop that removes the final element from the array.
$array = array_pop($array);
So if you run this twice, you will remove the final 2 elements from the array.
This is how I'd do it (and I hope I am not overthinking this :))
$stringArray = array();
$stringArray[] = '1,9';
$stringArray[] = '4,6';
$stringArray[] = '5,5';
$stringArray[] = '6,4';
$stringArray[] = '9,1';
foreach($stringArray as &$numString) {
$numString = explode(',', $numString);
usort($numString, function($a, $b) {return $a - $b;});
$numString = implode(',', $numString);
}
$a = array_unique($a);
print_r($a);
You basically explode every element into a subarray, sort it and then implode it back. After calling the array_unique, you're left with unique values in the array.
The output would be
Array
(
[0] => 1,9
[1] => 4,6
[2] => 5,5
)
The result you suggest treats [a,b] as equivalent to [b,a] which makes the problem a lot more complex. The code below gives the result you asked for, but without really understanding what the problem is that you are trying to fix and whether [1,9] is equivalent to [9,1] in the solution:
$a=array(array(1,9),array(4,6),...
$dup=array();
for ($i=0; $i<count($a) -1; $i++) {
for ($j=$i+1; $j<count($a); $j++) {
if (($a[$i][0]==$a[$j[0] && $a[$i][1]==$a[$j[1])
|| ($a[$i][0]==$a[$j[1] && $a[$i][1]==$a[$j[0])) {
$dup[]=$j;
}
}
}
foreach ($dup as $i) {
unset($a[$i]);
}
So I'm actually going to assume your question to have a different meaning than everyone else did. I believe what you're asking is:
How do you filter out array items where a reverse of the item has already been used?
<?php
// The example set you gave
$numberSets = [[1, 9], [4, 6], [5, 5], [6, 4], [9, 1]];
// Initialize an empty array to keep track of what we've seen
$keys = [];
// We use array filter to get rid of items we don't want
// (Notice that we use & on $keys, so that we can update the variable in the global scope)
$numberSets = array_filter($numberSets, function($set) use(&$keys) {
// Reverse the array
$set = array_reverse($set);
// Create a string of the items
$key = implode('', $set);
// Get the reverse of the numbers
$reversedKey = strrev($key);
// If the palindrome of our string was used, return false to filter
if (isset($keys[$reversedKey])) {
return false;
}
// Set the key so it's not used again
// Since $keys is being passed by reference it is updated in global scope
$keys[$key] = true;
// Return true to NOT filter this item, since it or it's reverse were not matched
return true;
});
var_dump($numberSets);
$string = "The complete archive of The New York Times can now be searched from NYTimes.com " //the actual input is unknown, it would be read from textarea
$size = the longest word length from the string
I assigned and initialized array in for loop, for example array1, array2 ....arrayN, here is how i did
for ($i = 1; $i <= $size; $i++) {
${"array" . $i} = array();
}
so the $string would be divided in the length of the word
$array1 = [""];
$array2 = ["of", "be", ...]
$array3 = ["the", "can", "now", ...] and so on
So, my question is how to assign in simple for loop or foreach loop $string value to $array1, $array2, $array3 ....., since the input text or the size of the longest word is unknown
I'd probably start with $words = explode(' ', $string)
then sort the string by word length
usort($words, function($word1, $word2) {
if (strlen($word1) == strlen($word2)) {
return 0;
}
return (strlen($word1) < strlen($word2)) ? -1 : 1;
});
$longestWordSize = strlen(last($words));
Loop over the words and place in their respective buckets.
Rather than separate variables for each length array, you should consider something like
$sortedWords = array(
1 => array('a', 'I'),
2 => array('to', 'be', 'or', 'is'),
3 => array('not', 'the'),
);
by looping over the words you don't need to know the maximum word length.
The final solution is as simple as
foreach ($words as $word) {
$wordLength = strlen($word);
$sortedWords[ $wordLength ][] = $word;
}
You could use something like this:
$words = explode(" ", $string);
foreach ($words as $w) {
array_push(${"array" . strlen($w)}, $w);
}
This splits up $string into an array of $words and then evaluates each word for length and pushes that word to the appropriate array.
you can use explode().
$string = "The complete archive of The New York Times can now be searched from NYTimes.com " ;
$arr=explode(" ",$string);
$count=count($arr);
$big=0;
for ($i = 0; $i < $count; $i++) {
$p=strlen($arr[$i]);
if($big<$p){ $big_val=$arr[$i]; $big=$p;}
}
echo $big_val;
Just use the word length as the index and append [] each word:
foreach(explode(' ', $string) as $word) {
$array[strlen($word)][] = $word;
}
To remove duplicates $array = array_map('array_unique', $array);.
Yields:
Array
(
[3] => Array
(
[0] => The
[2] => New
[3] => can
[4] => now
)
[8] => Array
(
[0] => complete
[1] => searched
)
[7] => Array
(
[0] => archive
)
[2] => Array
(
[0] => of
[1] => be
)
[4] => Array
(
[0] => York
)
[5] => Array
(
[0] => Times
)
)
If you want to re-index the main array use array_values() and to re-index the subarrays use array_map() with array_values().
I have an array:
$array = Array
(
[0] => qst
[1] => insert_question_note
[2] => preview_ans
[3] => _preview
[4] => view_structure_answer_preview
[5] => index
}
I need to unset the array keys based on elements in
$array_elements_to_be_remove = array('qst','_preview'); // or any string start with '_'
I tried to use:
$array_key = array_search('qst', $array);
unset($array[$array_key]);
$array_key_1 = array_search('_preview', $array);
unset($array[$array_key_1]);
Is there any other better ways to search batch of elements in $array ?
I expect that if I can use array search like this:
$array_keys_to_be_unset = array_search($array_elements_to_be_remove, $array);
I found a way to search the string if it is start with '_' as below:
substr('_thestring', 0, 1)
Any ideas how to do that?
You could use array_filter
$array = Array(
0 => 'qst',
1 => 'insert_question_note',
2 => 'preview_ans',
3 => '_preview',
4 => 'view_structure_answer_preview',
5 => 'index'
);
$array_elements_to_be_remove = array('qst', '_preview'); // or any string start with '_'
$new_array = array_filter($array, function($item)use($array_elements_to_be_remove) {
if (in_array($item, $array_elements_to_be_remove) || $item[0] == '_')
return false; // if value in $array_elements_to_be_remove or any string start with '_'
else
return true;
});
var_dump($new_array);
You can use php build function array_diff:
$arr=array_diff($array1, $array2);
Refer this php docs
I have the following array:
$list = array('item1','item2','item3','item4','item5','item6');
i need to take this array and break it into smaller arrays within 1 array for the csv. Each small array needs to have '999999' at index 0, followed by the next two items in the $list array. So the final result would be like this:
$newList = array(
array(999999, "item1" , "item2"),
array(999999, "item3" , "item4"),
array(999999, "item5" , "item6")
);
The original list array may contain up to 100 values at sometimes. What is the best way to achieve this?
Here's a different way of doing it, please see the comment as to where you place your additional elements to be prepended (you could add a second array into the merge at the end to add elements after the 2 list items too!)
See here for working example: http://codepad.org/hucpT5Yo
<?php
$list = array('item1','item2','item3','item4','item5','item6');
$list_chunks = array_chunk($list,2);
$list_chunks2 = array_map(
create_function(
'$x',
'return array_merge(array(
/* This array is prepended to the second,
add as many elements as you like */
999999,
"another element to add",
483274832
),
$x);'),
$list_chunks);
print_r($list_chunks2);
?>
$idx = 0;
$newarray = array();
$temparray = array('999999');
foreach($oldarray as $value) {
$temparray[] = $value;
if ((++$idx % 2)) == 0) {
$newarray[] = $temparray;
$temparray = array('999999');
}
}
Break your flat array into an array 2-element rows with array_chunk(), then call array_merge() on each row with the static value 999999 nested in an array and nominated as the first argument.
The modern syntax for the chunk-n-merge technique demonstrated by #Lee looks like this:
Code: (Demo)
$list = ['item1','item2','item3','item4','item5','item6'];
var_export(
array_map(fn($row) => array_merge([999999], $row), array_chunk($list, 2))
);
Output:
array (
0 =>
array (
0 => 999999,
1 => 'item1',
2 => 'item2',
),
1 =>
array (
0 => 999999,
1 => 'item3',
2 => 'item4',
),
2 =>
array (
0 => 999999,
1 => 'item5',
2 => 'item6',
),
)
I have this PHP one dimensional array:
Array
(
[Female--N] => 11
[Male--N] => 11
[Humans--N] => 11
[Adult--N] => 8
[Adolescent--N] => 8
[Reaction Time-physiology--N] => 6
[Acoustic Stimulation-methods--N] => 6
[Schizophrenia-genetics--Y] => 5
[Motion Perception--N] => 3
)
And i want a new array from this that looks like (i think this tow-dimensional..?):
Array
(
[Female][N] => 11
[Male][N] => 11
[Humans][N] => 11
[Adult][N] => 8
[Adolescent][N] => 8
[Reaction Time-physiology][N] => 6
[Acoustic Stimulation-methods][N] => 6
[Schizophrenia-genetics][Y] => 5
[Motion Perception][N] => 3
)
Can i use split method on key elements?
Little bit harder... i also need to split on the single '_' underscore, i did this to prevent the columns getting mixed up... But the example below doesn't do the job right...
$new_array = array();
foreach($MeshtagsArray as $key => $value) {
$parts = explode('__', $key, 2);
$parts2 = explode('_', $key, 2);
$new_array[] = array(
'discriptor' => $parts[0],
'qualifier' => $parts2[1],
'major' => $parts[1],
'#occurence' => $value
);
So the output should be something like:
[0] => Array
(
[discriptor] => Female
[qualifier] =>
[major] => N
[#occurence] => 11
........
[5] => Array
(
[discriptor] => Reaction Time
[qualifier] => physiology
[major] => N
[#occurence] => 6
Best regards,
Thijs
UPDATED
$new_array = array();
foreach($old_array as $key => $value) {
$parts1 = explode('--', $key, 2);
$parts2 = explode('-', $parts1[0], 2);
$new_array[] = array(
'descriptor' => $parts2[0],
'qualifier' => count($parts2) > 1 ? $parts2[1] : '',
'major' => $parts1[1],
'#occurence' => $value
);
}
$new_array will now be a numerically indexed, multidimensional array. Each top level key will contain an associative array of the elements you require.
In the future, feel free to explain the entire problem from the beginning, that way we can all better help you!
Explanation
According to php.net:
array explode ( string $delimiter , string $string [, int $limit ] )
Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string delimiter.
The array in your problem is associative; it's keys are strings. This makes it is a simple matter to iterate over the array with foreach and explode the keys into parts. I use a limit parameter to ensure that there will be no more than two parts.
Also, since one delimiter is a doubled version of the other, we have to first explode on the double -- delimiter, and then explode on the single - delimiter.
Technically, we could have used a single explode—with no limit parameter—and the single - delimiter. Then we could have inferred which element part belonged where. However, sometimes there is no qualifier. To get around this problem, I've used two explodes, and a ternary operator that counts the returned number of elements from the second explode.
Try this function:
function convertArray($array)
{
$return = array();
foreach ($array as $key=>$value)
{
$exploded = explode('--', $key);
$return[$exploded[0]][$exploded[1]] = $value;
}
return $return;
}
Assuming you are splitting on -- and you want a two dimensional array, try the following.
foreach ($the_array as $key => $value) {
// split key into new indexes
$indexes = explode('--', $key);
if (count($indexes) == 2) {
// create new dimension and set value
$the_array[$indexes[0]][$indexes[1]] = $value;
// remove old index
unset($the_array[$key]);
}
}
Note: This converts on the original array and ensures the key contains --