combining array_push and array_flip - php

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.

Related

PHP: Delete Array from 2D-Array

I am uploading a CSV file/report with 10 columns but at the end of the CSV file there are a few lines that just give details about the report like
Generated By: XXX
Company Name
Report Run # 2019-03-14
When I load the array, the keys are just numeric (from 0-9) but I wanted to make it be an associative array based on the column headers. Unfortunately this will not work for the last few lines since the array dimensions are different (1 vs 10)
Here is my code:
$csv = array_map('str_getcsv', file($_FILES['file']['tmp_name']));
array_walk($csv, function(&$a) use ($csv) {
if(count($csv[0]) != count($a)) {
$a = null; // Remove the array
} else {
$a = array_combine($csv[0], $a);
}
});
array_shift($csv); # remove column header
When I do $a = null; it sort of 'deletes it' by replacing it with NULL. When I iterate through the arrays I do if(is_null($row)) continue; to ignore the NULL element. Is there a way to actually delete the array?
I think it's more straightforward without array_walk. array_walk is just going to apply the function to every member of the array. Setting it to null doesn't mean it's gone, it just has a null value as you've seen. If you really want it gone, you need to unset it. Just refer to $csv by key and unset the ones you don't want.
$keys = array_shift($csv);
$expected_count = count($keys);
foreach ($csv as $index => $values) {
if (count($values) == $expected_count) {
$csv[$index] = array_combine($keys, $values);
} else {
unset($csv[$index]);
}
}
Array_filter($csv); afterwards will remove all null/false/0 from your array.
So it may be smarter to write a custom function to remove null only.

Find pairings in a two-dimensional array

I have a two-dimensional array and look for a way to find the all double entries. E.g. if the array is of the form
$a = array(
array('a','b','c'),
array('d','a','e'),
array('d','c','b')
)
the function should return the list
array(array(0,0),array(1,1)) // Since $a[0,0]=$a[1,1]
array(array(0,1),array(2,2)) // Since $a[0,1]=$a[2,2]
array(array(0,2),array(2,1)) // Since $a[0,2]=$a[2,1]
array(array(1,0),array(2,0)) // Since $a[1,0]=$a[2,0]
array(1,2) // Unmatched
Is there an elegant/efficient way to implement this?
With a nested loop. Use the values as keys in the result and append the coordinates as arrays under those keys.
foreach ($a as $x => $inner) {
foreach ($inner as $y => $value) {
$result[$value][] = [$x, $y];
}
}
The $result will contain sets of coordinates for all the given values. You can group the results by size of set to identify which values are unmatched, pairs, or have even greater than two occurrences (if that's possible).
foreach ($result as $value => $set) {
$sets[count($set)][$value] = $set;
}

how do i get data from csv and put in variable and get only the value that i want

Example
I have CSV file that contains data of random number example data in CSV :
639123456789,73999999999,739222222222,839444444444,8639555555555....more
So, if I upload it, I want it to explode in a variable or in an array as long as I get the specific data. example of data I want to get is all 2 first line starting at 73 be extract so meaning all numbers that start with 73 only.
Example: 73999999999,739222222222
I have tried it by using only 1 number using split,substr and explode function but my problem is if the user input a CSV bulk data with no limit.
You can use substr() and loop through your array deleting the elements that do not match.
$str = '639123456789,73999999999,739222222222,839444444444,8639555555555';
$array = explode(',', $str); //Convert your string to an array.
$searchString = '73'; //Set the value your looking for.
foreach($array as $key=>$value){
if(substr($value, 0, 2) != $searchString){ //This will test first two characters.
unset($array[$key]);
}
}
$array = array_values($array);
print_r($array);
This will output:
Array
(
[0] => 73999999999
[1] => 739222222222
)
Updated
This will make a new array with only the numbers you want in it, leaving the original array untouched.
$str = '639123456789,73999999999,739222222222,839444444444,739222222222,839444444444,839444444444,73999999999';
$array = explode(',', $str);
$searchString = '73';
foreach($array as $key=>$value){
if(substr($value, 0, 2) == $searchString){
$results[] = $value;
}
}
print_r($results);

array_unique for rearranged values

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);

Key Value Array From String

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.

Categories