Efficient array value replacement - php

I have an array of values in PHP looking something like this:
$test = array (
array( 'val' => 2, 'color' => 'blue' ),
array( 'val' => 5, 'color' => 'green' ),
);
I want to go through all elements of $test and add 1 to all val indices. Now I realize a foreach loop could work, but I am looking for something a little more efficient. The array will potentially have 10's of thousands of elements and hundreds of sub-elements.
I am wondering if there is some type of way that PHP can go through and modify just that index throughout the entire array, based on the argument that I set.

you can use array_walk and a closure to do it
array_walk($yourArray,function(&$col){$col['val']++});

Related

Multidimensional Array Not Echoing As Expected

I am setting this array manually:
$schools = array(
'Indiana University'=>array(
'initials'=>'IU',
'color'=>'red',
'directory'=>'indiana'
)
);
But it won't echo "IU" when I use:
echo $schools[0][0];
It does show correctly when I do:
print_r($schools);
I'm sure I'm messing up something dumb, but I have no idea what and I've been staring at it for hours. This array is actually part of a larger array with multiple universities, but when I trim it down to just this, it doesn't work.
PHP arrays support two types of keys - numerical and strings.
If you just push a value onto an array, it will use numerical keys by default. E.g.
$schools[] = 'Indiana University';
echo $schools[0]; // Indiana University
However, when you use string keys, you access the array values using the string key. E.g.
$schools = array(
'Indiana University' => array(
'initials' => 'IU',
'color' => 'red',
'directory' => 'indiana'
)
);
echo $schools['Indiana University']['initials']; // UI

Compare associative array with simple array in php

I have a simple session array and I'm pushing page titles in it, as strings:
$_SESSION['sesArray'][] = $pageTitle;
and another predefined associative array with page titles and links:
$assoc=array(array('title' => 'page title', 'link' => 'page link'));
The session array gets flooded with titles so I'm taking out duplicates:
$array1 = array_unique($_SESSION['sesArray']);
My question is: how can I compare the $assoc array against $array1 to check for page titles that exist in both and eliminate them, ending up with another array that contains unique titles along with the link?
I have tried using:
$result= array_diff_key($assoc, $array1 );
But some duplicate titles are indeed removed and some are not.
Any ideas?
ETA data:
$array1= array('Museum', 'Club');
$assoc= array(array('title' => 'Museum', 'link' => 'museum.php' ),
array('title' => 'club', 'link' => 'club.php'));
You are not really doing a diff because an array of arrays is by definition going to have nothing in common with an array of scalars. What you need to do is filter $assoc based on the contents of $array1. Try this:
$array1= array('Museum','Club');
$assoc= array(array('title' => 'Museum', 'link' => 'museum.php' ),
array('title' => 'club', 'link' => 'club.php'));
$fn = function($arr) use ($array1) {
return !in_array($arr['title'], $array1);
};
$result =array_filter($assoc, $fn);
Ah, the infamous tech-interview problem ("compare 2 arrays and to find common entries").
try something along the lines of:
$ass = array_keys($assoc);
foreach($ass as $a)
{
while (isset($_SESSION['sesArray'][$a]))
{
unset($_SESSION['sesArray'][$a]);
}
}
The way PHP associates its tuple arrays allows you to avoid the ugly O(n^2) complexity of this issue.

Reorganize an array by 'id' index of nested arrays

I have an array that looks like this:
Array([0]=>Array([id]=>7 [name]=foo) [1]=>Array([id]=>10 [name]=bar) [2]=>Array([id]=>15 [name]=baz))
Each index contains an another array with various elements including an 'id'. I would like to "go up" a level, such that my top-level array is indexed by the ID element of the corresponding nested arrays, but that index still contains an array with all of the elements that were in the sub arrays?
In other words, how can I use PHP to turn the above array into this:
Array([7]=>Array([id]=>7 [name]=foo) [10]=>Array([id]=>10 [name]=bar) [15]=>Array([id]=>15 [name]=baz))
What you need to do here is extract the ids from each sub-array in your input. If you have these as an array of ids, you are just an array_combine call away from re-indexing your original array to use these ids as the keys.
You can produce such an array of ids using array_map, which leads to:
// input data
$array = array(array('id' => '7', 'name' => 'foo'),array('id' => 10, 'name' => 'bar'));
// extract ids from the input array
$ids = array_map(function($arr) { return $arr['id']; }, $array);
// "reindex" original array using ids as array keys, keep original values
$result = array_combine($ids, $array);
print_r($result);
The syntax I 've used for the anonymous function (first argument to array_map) requires PHP >= 5.3, but you can achieve the same (although a bit less conveniently) with create_function in any PHP version you 'd not be ashamed of using.
See it in action.
In modern, supported versions of PHP, this whole task can be achieved with array_column() alone.
Using null as the second parameter will leave the rows unchanged.
Using id as the 3rd parameter will assign those columnar values as the new first level keys. Be aware that if these columnar values are not unique, subsequently encountered duplicates will overwrite previously encountered rows with the same id value -- this is because keys cannot be duplicates on a given level in an array.
DO NOT bother calling array_combine(), it is simply unnecessary/indirect.
Code: (Demo)
$array = [
['id' => 7, 'name' => 'foo'],
['id' => 10, 'name' => 'bar'],
['id' => 15, 'name' => 'baz'],
];
var_export(
array_column($array, null, 'id')
);
Output:
array (
7 =>
array (
'id' => 7,
'name' => 'foo',
),
10 =>
array (
'id' => 10,
'name' => 'bar',
),
15 =>
array (
'id' => 15,
'name' => 'baz',
),
)
Try this:
$newArray = array();
foreach($oldArray as $key => $value) {
$newArray[$value['id']] = $value;
}
Since PHP 5.5.0, you can shorten the code by using array_column() instead of array_map().
$result = array_combine(array_column($array, 'id'), $array);

Replace array key integers with string

$string = "php, photoshop, css";
I'm producing an array from the comma separated values above using the str_getcsv() function:
$array = str_getcsv($string);
Result:
Array ( [0] => php [1] => photoshop [2] => css )
How can I replace the key integers with a string tag for all elements like seen below?
Array ( [tag] => php [tag] => photoshop [tag] => css )
Edit: if not possible what alternative can I apply? I need the array keys to be identical for a dynamic query with multiple OR clauses
e.g.
SELECT * FROM ('posts') WHERE 'tag' LIKE '%php% OR 'tag' LIKE '%photoshop% OR 'tag' LIKE '%css%'
I'm producing the query via a function that uses the array key as a column name and value as criteria.
That is not possible. You can have only one item per key. But in your example, the string "tag" would be the key of every item.
The other way arround would work. So having an array like this:
array('php' => 'tag', 'photoshop' => 'tag', 'css' => 'tag');
This might help you, if you want to save the "type" of each entry in an array. But as all the entries of your array seems to be from the same type, just forget about the "tag" and only store the values in a numeric array.
Or you can use a multidimensional array within the numeric array to save the type:
array(
0 => array( 'type' => 'tag', 'value' => 'php' ),
1 => array( 'type' => 'tag', 'value' => 'photoshop' ),
2 => array( 'type' => 'tag', 'value' => 'css' )
);
But still using just an numeric array should be fine if all the entries have the same type. I can even think of a last one:
array(
'tag' => array('php', 'photoshop', 'css')
);
But even if I repeat myself: Just use an ordinary array and name it something like $tag!
BTW: explode(', ', %string) is the more common function to split a string.
To build SQL statement you might do something like this:
// ... inside you build function
if(is_array($value)){
$sql .= "'".$key."' LIKE '%."implode("%' OR '".$key."' LIKE '%", $value)."%'";
} else {
$sql .= "'".$key."' LIKE '%".$value."%'";
}
This might look confusing but it's much cleaner than runnig into two foreach-loops building the query.
That won't work. Your array keys have to be unique, or subsequent additions will simply overwrite the previous key.
As the others said, keys have to be unique. Otherwise, which element should be returned if you access $arr['tag']? If you now say "all of them", then create a nested array:
$array = array();
$array['tag'] = str_getcsv($string);
The value $array['tag'] will be another array (the one you already have) with numerical keys. This makes, because you have a list of tags and lists can be represented as arrays too.
Understanding arrays is very important if you want to work with PHP, so I suggest to read the array manual.
Assuming you know the size of your array beforehand
$tags = array("tag1","tag2","tag3");
$data = array("php","photoshop","css");
$myarray = array();
for ($i=0; $i<count($data); $i++) {
$myarray[$i] = array($data[$i], $tags[$i]);
}
Then
echo $myarray[0][0] . ", " . $myarray[0][1];
Outputs:
php, tag1

Can I store an array within a multidimensional array? (PHP)

It is possible to put an array into a multi dim array? I have a list of user settings that I want to return in a JSON array and also have another array stored in that JSON array...what is the best way to do that if it isn't possible?
A multi dimension is already an array inside an array. So there's nothing stopping you from putting another array in there. Sort of like dreams within dreams :P
Just use associative arrays if you want to give your array meaning
array(
'SETTINGS' => array(
'arr1' => array( 0, 1),
'arr2' => array( 0, 1)
),
'DATA' => array(
'arr1' => array( 0, 1),
'arr2' => array( 0, 1)
)
)
EDIT
To answer your comment, $output_files[$file_id]['shared_with'] = $shared_info; translates to (your comment had an extra ] which I removed)
$shared_info = array(1, 2, 3);
$file_id = 3;
$output_files = array(
'3' => array(
'shared_with' => array() //this is where $shared_info will get assigned
)
);
//you don't actually have to declare it an empty array. I just did it to demonstrate.
$output_files[$file_id]['shared_with'] = $shared_info; // now that empty array is replaced.
any array key can have an array value in php, as well as in json.
php:
'key' => array(...)
json:
"key" : [...]
note: php doesn't support multidimensional arrays as in C or C++. it's just an array element containing another array.

Categories