This is my array
$input = array("ASTY","PLO","KNGO","c","LOP","OPL","HONGO","TSAY");
here,
ASTY,TSAY = contains same letters. I need to keep first one.
PLO,LOP,OPL= contains same letters. I need to keep first one.
So, my desired output array
$output = array("ASTY","PLO","KNGO","c","HONGO");
Is there any builtin function to do this?
array_unique works fine for non-rearranged word.
To compare whether any two values are equal in this scenario, you would simply order the letters and compare the ordered value. To deduplicate the array, use the fact that arrays keys are unique:
$unique = [];
foreach ($input as $word) {
$key = str_split($word);
sort($key);
$unique[join($key)] = $word;
}
// optionally:
$unique = array_values($unique);
Related
I have 2 arrays and want to combine into third array with one array as key and another as value. I tried to use array_combine(), but the function will eliminate all the repeated keys, so I want the result array as a 2d array. The sample array is as below:
$keys = {0,1,2,0,1,2,0,1,2};
$values = {a,b,c,d,e,f,g,h,i};
$result = array(
[0]=>array(0=>a,1=>b,2=>c),
[1]=>array(0=>d,1=>e,2=>f),
[2]=>array(0=>g,1=>h,2=>i)
);
//What i am using right now is:
$result = array_combine($keys,$values);
But it only returns array(0=>g,2=>h,3=>i). Any advice would be appreciated!
You can do it like below:-
<?php
$keys = array(0,1,2,0,1,2,0,1,2);
$values = array('a','b','c','d','e','f','g','h','i');
$values = array_chunk($values,count(array_unique($keys)));
foreach($values as &$value){
$value = array_combine(array_unique($keys),$value);
}
print_r($values);
https://eval.in/859753
Yes the above is working and i give upvote too for this but i dont know why you combine into the foreach loop its not necessary. The results are given in only in second line. Can you describe?
<?php
$keys = array(0,1,2,0,1,2,0,1,2);
$values = array('a','b','c','d','e','f','g','h','i');
$v = array_chunk($values,count(array_unique($keys)));
echo "<pre>";print_r($v);
?>
https://eval.in/859759
As a more flexible/robust solution, push key-value pairs into new rows whenever the key's value is already in the currently targeted row. In other words, there will never be an attempt to write a key into a row that already contains that particular key.
This can be expected to be highly efficient because there are no iterated function calls ...no function calls at all, really.
Code: (Demo)
$result = [];
foreach ($keys as $i => $key) {
$counter[$key] = ($counter[$key] ?? -1) + 1;
$result[$counter[$key]][$key] = $values[$i];
}
var_export($result);
I have a key value pair string that I would like to convert to a functional array. So that I can reference the values using their key. Right now I have this:
$Array = "'Type'=>'Honda', 'Color'=>'Red'";
$MyArray = array($Array);
This is not bringing back a functional key/value array. My key value pairs are in a variable string which means the => is part of the string and i think this is where my problem is. Any help would be appreciated. All i am trying to do is convert the string to a functional key/value pair where I can grab the values using the key. My data is in a string so please don't reply with the answer "take them out of the string." I am aware that this will work:
$MyArray = array('Type'=>'Honda', 'Color'=>'Red');
But my probem is that the the data is already in the form of a string. Thank you for any help.
There is no direct way to do this. As such, you'll need to write a custom function to build the keys and values for each element.
An example specification for the custom function:
Use explode() to split each element based on the comma.
Iterate over the result and:
explode() on =>
Remove unnecessary characters, i.e. single quotes
Store the first element as the key and the second element as the value
Return the array.
Note: if your strings contain delimiters this will be more challenging.
You do need to "take them out of the string", as you say. But you don't have to do it manually. The other answer uses explode; that's a fine method. I'll show you another - what I think is the easiest way is to use preg_match_all() (documentation), like this:
$string = "'Type'=>'Honda', 'Color'=>'Red'";
$array = array();
preg_match_all("/'(.+?)'=>'(.+?)'/", $string, $matches);
foreach ($matches[1] as $i => $key) {
$array[$key] = $matches[2][$i];
}
var_dump($array);
You need to parse the string and extract the data:
$string = "'Type'=>'Honda', 'Color'=>'Red'";
$elements = explode(",",$string);
$keyValuePairs = array();
foreach($elements as $element){
$keyValuePairs[] = explode("=>",$element);
}
var_dump($keyValuePairs);
Now you can create your on array using the $keyValuePairs array.
Here is an example of one way you can do it -
$Array = "'Type'=>'Honda', 'Color'=>'Red'";
$realArray = explode(',',$Array); // get the items that will be in the new array
$newArray = array();
foreach($realArray as $value) {
$arrayBit = explode('=>', $value); // split each item
$key = str_replace('\'', '', $arrayBit[0]); // clean up
$newValue = str_replace('\'', '', $arrayBit[1]); // clean up
$newArray[$key] = $newValue; // place the new item in the new array
}
print_r($newArray); // just to see the new array
echo $newArray['Type']; // calls out one element
This could be placed into a function that could be extended so each item gets cleaned up properly (instead of the brute force method shown here), but demonstrates the basics.
I have an array that contains other arrays of US colleges broken down by the first letter of the alphabet. I've setup a test page so that you can see the array using print_r. That page is:
http://apps.richardmethod.com/Prehealth/Newpublic/test.php
In order to create that array, I used the following code:
$alphabetized = array();
foreach (range('A', 'Z') as $letter) {
// create new array based on letter
$alphabetized[$letter] = array();
// loop through results and add to array
foreach ( $users as $user ) {
$firstletter = substr($user->Schoolname, 0, 1);
if ( $letter == $firstletter ) {
array_unshift( $alphabetized[$letter], $user );
}
}
}
Now, I want to split the array so that a certain range of letters is in each array. For example,
arrayABCEFGH - would contain the schools that begin with the letters A, B, C, D, E, F, G, and H.
My question is, should I modify the code above so that I achieve this before I do one big array, OR should I do it after?
And here is the big question . . if so, how? :-)
Thanks in advance for any help. It's greatly appreciated.
First off, the code to generate the array can be made easier by only iteratating over $users:
$alphabetized = array();
// loop through results and add to array
foreach ($users as $user) {
$firstletter = strtoupper($user->Schoolname[0]);
$alphabetized[$firstletter][] = $user;
}
// sort by first letter (optional)
ksort($alphabetized);
To retrieve the first 8 entries you could use array_slice:
array_slice($alphabetized, 0, 8);
Assuming that all first letters are actually used and you used ksort() on the full array that also gives you from A - H. Otherwise you have to use array_intersect_key() and the flipped range of letters you wish to query on.
array_intersect_key($alphabetized, array_flip(range('A', 'H')));
If you don't need a full copy of the array, then you should encapsulate the above code in a function that has an array as its argument ($letterRange), which will hold the specific array identifiers (letters) to be in the final array.
Then you would need to encapsulate the code within the foreach using an if block:
if (in_array($letter, $letterRange)) { ... }
This would result in an array only containing the letter arrays for the specified letters in $letterRange.
You could write a simple function that takes an array, and an array of keys to extract from that array, and returns an array containing just those keys and their values. A sort of array_slice for non-numeric keys:
function values_at($array, $keys) {
return array_intersect_key($array, array_flip($keys));
}
Which you can then call like this to get what you want out of your alphabetized list:
$arrayABCDEFGH = values_at($alphabetized, range('A','H'));
I'm storing words in an array. Every time I add new words from a form, it appends them to the existing array.
I'd like to make sure words are stored in the key of the array and not the value. I just use array_flip to do it the first time, but when I append new words they get stored as values.
I'm sure this is simple, but how can I make sure the array is always ordered to store words as keys?! Thanks in advance...
Here's my code: $_SESSION['words'] is the existing array of words and $_POST['additions'] is the new incoming words to be added:
if (isset($_POST['additions']) === true) {
// do cleanup
$additions = explode(",", $_POST['additions']); // create array from $_POST['additions']
$additions = array_map('trim', $additions); // remove whitespace
$additions = array_filter($additions); // remove blank array elements
$additions = preg_replace("/,(?![^,]*,)/",'',$additions); // remove stray characters
foreach($additions as $key => $value) {
// append content to $_SESSION['words']
array_push($_SESSION['words'], $value);
}
// swap all the array values with the array keys
$_SESSION['words'] = array_flip($_SESSION['words']);
// swap keys with values
foreach($_SESSION['words'] as $key => $value) {
$key = $value;
$value = "";
}
Here you go:
foreach($additions as $key => $value) {
// append content to $_SESSION['words']
$_SESSION['words'][$value]=count($_SESSION['words'])+1;
}
No need to flip around; replace the first foreach loop with this code, and remove everything after it.
What i am trying to do is really but i am going into a lot of detail to make sure it is easily understandable.
I have a array that has a few strings in it. I then have another that has few other short strings in it usually one or two words.
I need it so that if my app finds one of the string words in the second array, in one of the first arrays string it will proceed to the next action.
So for example if one of the strings in the first array is "This is PHP Code" and then one of the strings in the second is "PHP" Then it finds a match it proceeds to the next action. I can do this using this code:
for ( $i = 0; $i < count($Array); $i++) {
$Arrays = strpos($Array[$i],$SecondArray[$i]);
if ($Arrays === false) {
echo 'Not Found Array String';
}
else {
echo 'Found Array String';
However this only compares the First Array object at the current index in the loop with the Second Array objects current index in the loop.
I need it to compare all the values in the array, so that it searches every value in the first array for the First Value in the second array, then every value in the First array for the Second value in the second array and so on.
I think i have to do two loops? I tried this but had problems with the array only returning the first value.
If anyone could help it would be appreciated!
Ill mark the correct answer and + 1 any helpful comments!
Thanks!
Maybe the following is a solution:
// loop through array1
foreach($array1 as $line) {
// check if the word is found
$word_found = false;
// explode on every word
$words = explode(" ", $line);
// loop through every word
foreach($words as $word) {
if(in_array($word, $array2)) {
$word_found = true;
break;
}
}
// if the word is found do something
if($word_found) {
echo "There is a match found.";
} else {
echo "No match found."
}
}
Should give you the result you want. I'm absolute sure there is a more efficient way to do this.. but thats for you 2 find out i quess.. good luck
You can first normalize your data and then use PHP's build in array functions to get the intersection between two arrays.
First of all convert each array with those multiple string with multiple words in there into an array only containing all words.
A helpful function to get all words from a string can be str_word_count.
Then compare those two "all words" arrays with each other using array_intersect.
Something like this:
$words1 = array_unique(str_word_count(implode(' ', $Array), 1));
$words2 = array_unique(str_word_count(implode(' ', $SecondArray), 1));
$intersection = array_intersect($words1, $words2);
if(count($intersection))
{
# there is a match!
}
function findUnit($packaging_units, $packaging)
{
foreach ($packaging_units as $packaging_unit) {
if (str_contains(strtoupper($packaging[3]), $packaging_unit)) {
return $packaging_unit;
}
}
}
Here First parameter is array and second one is variable to find