I have a result set of data that I want to write to an array in php. Here is my sample data:
**Name** **Abbrev**
Mike M
Tom T
Jim J
Using that data, I want to create an array in php that is of the following:
1|Mike|M
2|Tom|T
3|Jim|j
I tried array_push($values, 'name', 'abbreviation') [pseudo code], which gave me the following:
1|Mike
2|M
3|Tom
4|T
5|Jim
6|J
I need to do a look up against this array to get the same key value, if I look up "Mike" or "M".
What is the best way to write my result set into an array as set above where name and abbreviation share the same key?
PHP's not my top language, but try these:
array_push($values, array("Mike", "M"))
array_push($values, array("Tom", "T"))
array_push($values, array("Jim", "J"))
$name1 = $values[1][0]
$abbrev1 = $values[1][1]
or:
array_push($values, array("name" => "Mike", "abbrev" => "M"))
array_push($values, array("name" => "Tom", "abbrev" => "T"))
array_push($values, array("name" => "Jim", "abbrev" => "J"))
$name1 = $values[1]["name"]
$abbrev1 = $values[1]["abbrev"]
The trick is to use a nested array to pair the names and abbreviations in each entry.
$person = array('name' => 'Mike', 'initial' => 'M');
array_push($people, $person);
That said, I'm not sure why you're storing the data separately. The initial can be fetched directly from the name via substr($name, 0, 1).
You will need to create a two dimensional array to store more than one value.
Each row in your result set is already an array, so it will need to be added to your variable as an array.
array_push($values, array('name', 'abbreviation'));
maybe you create a simple class for that as the abbreviation is redundant information in your case
class Person
{
public $name;
pulbic function __construct($name)
{
$this->name = (string)$name;
}
public function getAbbrev()
{
return substr($this->name, 0, 1);
}
public function __get($prop)
{
if ($prop == 'abbrev') {
return $this->getAbbrev();
}
}
}
$persons = array(
new Person('Mike'),
new Person('Tom'),
new Person('Jim')
);
foreach ($persons as $person) {
echo "$person->name ($person->abbrev.)<br/>";
}
You could use two separate arrays, maybe like:
$values_names = array();
$values_initials = array();
array_push($values_names, 'Mike');
array_push($values_initials, 'M');
array_push($values_names, 'Tom');
array_push($values_initials, 'T');
array_push($values_names, 'Jim');
array_push($values_initials, 'J');
So you use two arrays, one for each of the second and third columns using the values in the first one as keys for both arrays.
php arrays work like hash lookup tables, so in order to achieve the desired result, you can initialize 2 keys, one with the actual value and the other one with a reference pointing to the first. For instance you could do:
$a = array('m' => 'value');
$a['mike'] = &$a['m']; //notice the end to pass by reference
if you try:
$a = array('m' => 'value');
$a['mike'] = &$a['m'];
print_r($a);
$a['m'] = 'new_value';
print_r($a);
$a['mike'] = 'new_value_2';
print_r($a);
the output will be:
Array
(
[m] => value
[mike] => value
)
Array
(
[m] => new_value
[mike] => new_value
)
Array
(
[m] => new_value_2
[mike] => new_value_2
)
have to set the same value to both Mike and M for keys.
Related
I have an array as such
$array = array{
'title' => "happy"
}
When i use Json encode, i get :
{"title":"happy"}
Later on in my code, i need to add some items in the $array like "Gender"
$array[] = array{
'Gender' => $gender
}
When i use Json encode, it becomes something like:
{"title":"happy","0":{"Gender":"female"}}
I really don't want the "0". I just want it to be :
{"title":"happy","Gender":"female"}
What am i doing wrong ?
You are creating a new array and then appending it to the end of the existing array.
You just want to add a new key to the existing array:
$array['Gender'] = $gender;
Do like this,
$array = array('title' => "happy");
$array['Gender'] = $gender;
json_encode($array);
DEMO
First you assign a filled array to $array. Later you add another array to the existing array.
Creating an array with content:
$array = array(
'title' => 'happpy'
);
Is the same as:
$array = array();
$array['title'] = 'happy';
When adding an extra value to the array you need to:
$array['gender'] = 'Your gender';
After the full array is created you can json_encode it.
Tip:
Merge two existing arrays by using the function array_merge().
$array[] = array('title' => "happy");
echo json_encode($array)."</br>";
//outputs : [{"title":"happy"}]
$array[] = array('Gender' => "female");
echo json_encode($array)."</br>";
//outputs :[{"title":"happy"},{"Gender":null}]
So far all my research has shown that this cannot be achieved without writing lengthy functions such as the solution here
Surely there is a simpler way of achieving this using the predefined PHP functions?
Just to be clear, I am trying to do the following:
$test = array(
'bla' => 123,
'bla2' => 1234,
'bla3' => 12345
);
// Call some cool function here and return the array where the
// the element with key 'bla2' has been shifted to the beginning like so
print_r($test);
// Prints bla2=1234, bla=>123 etc...
I have looked at using the following functions but have so far have not been able to write a solution myself.
array_unshift
array_merge
To Summarize
I would like to:
Move an element to the beginning of an array
... whilst maintaining the associative array keys
This seems, funny, to me. But here ya go:
$test = array(
'bla' => 123,
'bla2' => 1234,
'bla3' => 12345
);
//store value of key we want to move
$tmp = $test['bla2'];
//now remove this from the original array
unset($test['bla2']);
//then create a new array with the requested index at the beginning
$new = array_merge(array('bla2' => $tmp), $test);
print_r($new);
Output looks like:
Array
(
[bla2] => 1234
[bla] => 123
[bla3] => 12345
)
You could turn this into a simple function that takes-in a key and an array, then outputs the newly sorted array.
UPDATE
I'm not sure why I didn't default to using uksort, but you can do this a bit cleaner:
$test = array(
'bla' => 123,
'bla2' => 1234,
'bla3' => 12345
);
//create a function to handle sorting by keys
function sortStuff($a, $b) {
if ($a === 'bla2') {
return -1;
}
return 1;
}
//sort by keys using user-defined function
uksort($test, 'sortStuff');
print_r($test);
This returns the same output as the code above.
This isn't strictly the answer to Ben's question (is that bad?) - but this is optimised for bringing a list of items to the top of the list.
/**
* Moves any values that exist in the crumb array to the top of values
* #param $values array of options with id as key
* #param $crumbs array of crumbs with id as key
* #return array
* #fixme - need to move to crumb Class
*/
public static function crumbsToTop($values, $crumbs) {
$top = array();
foreach ($crumbs AS $key => $crumb) {
if (isset($values[$key])) {
$top[$key] = $values[$key];
unset($values[$key]);
}
}
return $top + $values;
}
if i have the following array:
array(
'var1' => 123,
'var2' => 234,
'var3' => 345
);
I would like to extract specific parts of this to build a new array i.e. var1 and var3.
The result i would be looking for is:
array(
'var1' => 123,
'var3' => 345
);
The example posted is very stripped down, in reality the array has a much larger number of keys and I am looking to extract a larger number of key and also some keys may or may not be present.
Is there a built in php function to do this?
Edit:
The keys to be extracted will be hardcoded as an array in the class i..e $this->keysToExtract
$result = array_intersect_key($yourarray,array_flip(array('var1','var3')));
So, with your edit:
$result = array_intersect_key($yourarray,array_flip($this->keysToExtract));
You don't need a built in function to do this, try this :
$this->keysToExtract = array('var1', 'var3'); // The keys you wish to transfer to the new array
// For each record in your initial array
foreach ($firstArray as $key => $value)
{
// If the key (ex : 'var1') is part of the desired keys
if (in_array($key, $this->keysToExtract)
{
$finalArray[$key] = $value; // Add to the new array
}
}
var_dump($finalArray);
Note that this is most likely the most efficient way to do this.
I am new to using multidimensional arrays with php, I have tried to stay away from them because they confused me, but now the time has come that I put them to good use. I have been trying to understand how they work and I am just not getting it.
What I am trying to do is populate results based on a string compare function, once I find some match to an 'item name', I would like the first slot to contain the 'item name', then I would like to increment the priority slot by 1.
So when when I'm all done populating my array, it is going to have a variety of different company names, each with their respective priority...
I am having trouble understanding how to declare and manipulate the following array:
$matches = array(
'name'=>array('somename'),
'priority'=>array($priority_level++)
);
So, in what you have, your variable $matches will point to a keyed array, the 'name' element of that array will be an indexed array with 1 entry 'somename', there will be a 'priority' entry with a value which is an indexed array with one entry = $priority_level.
I think, instead what you probably want is something like:
$matches[] = array(name => 'somename', $priority => $priority_level++);
That way, $matches is an indexed array, where each index holds a keyed array, so you could address them as:
$matches[0]['name'] and $matches[0]['priority'], which is more logical for most people.
Multi-dimensional arrays are easy. All they are is an array, where the elements are other arrays.
So, you could have 2 separate arrays:
$name = array('somename');
$priority = array(1);
Or you can have an array that has these 2 arrays as elements:
$matches = array(
'name' => array('somename'),
'priority' => array(1)
);
So, using $matches['name'] would be the same as using $name, they are both arrays, just stored differently.
echo $name[0]; //'somename';
echo $matches['name'][0]; //'somename';
So, to add another name to the $matches array, you can do this:
$matches['name'][] = 'Another Name';
$matches['priority'][] = 2;
print_r($matches); would output:
Array
(
[name] => Array
(
[0] => somename
[1] => Another Name
)
[priority] => Array
(
[0] => 1
[1] => 2
)
)
In this case, could this be also a solution with a single dimensional array?
$matches = array(
'company_1' => 0,
'company_2' => 0,
);
if (isset($matches['company_1'])) {
++$matches['company_1'];
} else {
$matches['company_1'] = 1;
}
It looks up whether the name is already in the list. If not, it sets an array_key for this value. If it finds an already existing value, it just raises the "priority".
In my opinion, an easier structure to work with would be something more like this one:
$matches = array(
array( 'name' => 'somename', 'priority' => $priority_level_for_this_match ),
array( 'name' => 'someothername', 'priority' => $priority_level_for_that_match )
)
To fill this array, start by making an empty one:
$matches = array();
Then, find all of your matches.
$match = array( 'name' => 'somename', 'priority' => $some_priority );
To add that array to your matches, just slap it on the end:
$matches[] = $match;
Once it's filled, you can easily iterate over it:
foreach($matches as $k => $v) {
// The value in this case is also an array, and can be indexed as such
echo( $v['name'] . ': ' . $v['priority'] . '<br>' );
}
You can also sort the matched arrays according to the priority:
function cmp($a, $b) {
if($a['priority'] == $b['priority'])
return 0;
return ($a['priority'] < $b['priority']) ? -1 : 1;
}
usort($matches, 'cmp');
(Sourced from this answer)
$matches['name'][0] --> 'somename'
$matches['priority'][0] ---> the incremented $priority_level value
Like David said in the comments on the question, it sounds like you're not using the right tool for the job. Try:
$priorities = array();
foreach($companies as $company) {
if (!isset($priorities[$company])) { $priorities[$company] = 0; }
$priorities[$company]++;
}
Then you can access the priorities by checking $priorities['SomeCompanyName'];.
Background: Trevor is working with a PHP implementation of a standard algorithm: take a main set of default name-value pairs, and update those name-value pairs, but only for those name-value pairs where a valid update value actually exists.
Problem: by default, PHP array_merge works like this ... it will overwrite a non-blank value with a blank value.
$aamain = Array('firstname'=>'peter','age'=>'32','nation'=>'');
$update = Array('firstname' => '','lastname' => 'griffin', age =>'33','nation'=>'usa');
print_r(array_merge($aamain,$update));
/*
Array
(
[firstname] => // <-- update set this to blank, NOT COOL!
[age] => 33 // <-- update set this to 33, thats cool
[lastname] => griffin // <-- update added this key-value pair, thats cool
[nation] => usa // <-- update filled in a blank, thats cool.
)
*/
Question: What's the fewest-lines-of-code way to do array_merge where blank values never overwrite already-existing values?
print_r(array_coolmerge($aamain,$update));
/*
Array
(
[firstname] => peter // <-- don't blank out a value if one already exists!
[age] => 33
[lastname] => griffin
[nation] => usa
)
*/
UPDATE: 2016-06-17T11:51:54 the question was updated with clarifying context and rename of variables.
Well, if you want a "clever" way to do it, here it is, but it may not be as readable as simply doing a loop.
$merged = array_merge(array_filter($foo, 'strval'), array_filter($bar, 'strval'));
edit: or using +...
array_replace_recursive($array, $array2);
This is the solution.
Try this:
$merged = array_map(
create_function('$foo,$bar','return ($bar?$bar:$foo);'),
$foobar,$feebar
);
Not the most readable solution, but it should replace only non-empty values, regardless of which order the arrays are passed..
Adjust to your needs:
# Replace keys in $foo
foreach ($foo as $key => $value) {
if ($value != '' || !isset($bar[$key])) continue;
$foo[$key] = $bar[$key];
}
# Add other keys in $bar
# Will not overwrite existing keys in $foo
$foo += $bar;
If you also want to keep the values that are blank in both arrays:
array_filter($foo) + array_filter($bar) + $foo + $bar
This will put duplicates into a new array, I don't know if this is what you want though.
<?php
$foobar = Array('firstname' => 'peter','age' => '33',);
$feebar = Array('firstname' => '','lastname' => 'griffin',);
$merged=$foobar;
foreach($feebar as $k=>$v){
if(isset($foobar[$k]))$merged[$k]=array($v,$foobar[$k]);
else $merged[$k]=$v;
}
print_r($merged);
?>
This will simply assure that feebar will never blank out a value in foobar:
<?php
$foobar = Array('firstname' => 'peter','age' => '33',);
$feebar = Array('firstname' => '','lastname' => 'griffin',);
$merged=$foobar;
foreach($feebar as $k=>$v) if($v)$merged[$k]=$v;
print_r($merged);
?>
or ofcourse,
<?
function cool_merge($array1,$array2){
$result=$array1;
foreach($array2 as $k=>$v) if($v)$result[$k]=$v;
return $result;
}
$foobar = Array('firstname' => 'peter','age' => '33',);
$feebar = Array('firstname' => '','lastname' => 'griffin',);
print_r(cool_merge($foobar,$feebar));
?>