php's explode array index - php

Using php's explode with the following code
$data="test_1, test_2, test_3";
$temp= explode(",",$data);
I get an array like this
array('0'=>'test_1', '1'=>'test_2', 2='test_3')
what I would like to have after explode
array('1'=>'test_1', '2'=>'test_2', 3='test_3')

You could something like this :
$temp = array_combine(range(1, count($temp)), array_values($temp));
uses array_combine() to create array using your existing values (using array_values()) and range() to create a new range from 1 to the size of your array
Working example here

Array indexes start at 0. If you really wanted to have the array start with one, you could explode it, then copy it to another array with your indexes defined as starting at 1 - but why?

You could use this possibly (untested)
$newArray=array_unshift($temp,' ');
unset($newArray[0]);

it is impossible using explode.
for($i = count($temp) - 1; $i >= 0; $i--)
$temp[$i + 1] = $temp[$i];
unset($temp[0]);

You couldn't do it directly, but this will do what you're after:
$temp=explode(',',',' . $data);
unset($temp[0]);
var_dump($temp);
array(3) {
[1]=>
string(6) "test_1"
[2]=>
string(7) " test_2"
[3]=>
string(7) " test_3"
}

Lloyd Watkin's answer makes the fewest function calls to achieve the expected result. It is certainly a superior answer to ManseUK's method which uses four functions in its one-liner after the string has been exploded.
Since this question is nearly 5 years, old there should be something valuable to add if anyone dare to chime in now...
I have two things to address:
The OP and Lloyd Watkins both fail to assign the correct delimiter to their explode method based on the sample string. The delimiter should be a comma followed by a space.
Sample Input:
$data="test_1, test_2, test_3";
No one has offered a one-liner solution that matches Lloyd's two-function approach. Here that is: (Demo)
$temp=array_slice(explode(", ",", $data"),1,null,true);
This two-function one-liner prepends the $data string with a comma then a space before exploding it. Then array_slice ignores the first empty element, and returns from the second element (1) to the end (null) while preserving the keys (true).
Output as desired:
array(
1 => 'test_1',
2 => 'test_2',
3 => 'test_3',
)

Related

How can I change array items?

I have an array containing links. I am trying to cut a part of those links. For example:
$array = [
"https://eksisozluk.com/merve-sanayin-pizzaciya-kapiyi-ciplak-acmasi--5868043?a=popular",
"https://eksisozluk.com/merve-sanayin-pizzaciya-kapiyi-ciplak-acmasi--5868043?a=popular"
];
I want change these links like below:
array(2) {
[0]=>
string(91) "https://eksisozluk.com/merve-sanayin"
[1]=>
string(91) "https://eksisozluk.com/merve-sanayin"
[2]=>
}
Is there any possible way to edit array items?
Given the array:
$array = [
"https://eksisozluk.com/merve-sanayin-pizzaciya-kapiyi-ciplak-acmasi--5868043?a=popular",
"https://eksisozluk.com/merve-sanayin-pizzaciya-kapiyi-ciplak-acmasi--5868043?a=popular"
];
Using array_walk() (modifies the array in place).
Using a regular expression this time:
function filter_url(&$item)
{
preg_match('|(https:\/\/\w+\.\w{2,4}\/\w+-\w+)-.+|', $item, $matches);
$item = $matches[1];
}
array_walk($array, 'filter_url');
(See it working here).
Note that filter_url passes the first parameter by reference, as explained in the documentation, so changes to each of the array items are performed in place and affect the original array.
Using array_map() (returns a modified array)
Simply using substr, since we know next to nothing about your actual requirements:
function clean_url($item)
{
return substr($item, 0, 36);
}
$new_array = array_map('clean_url', $array);
Working here.
The specifics of how actually filter the array elements are up to you.
The example shown here seems kinda pointless, since you are setting all elements exactly to the same value. If you know the lenght you can use substr, or you could just could write a more robust regex.
Since all the elements of your input array are the same in the example, I am going to assume this doesn't represent your actual input.
You could also iterate the array using either for, foreach or while, but either of those options seems less elegant when you have specific array functions to deal with this kind of situation.
There are multiple ways. One way is to iterate over the items and clip them with substr().
$arr = array("https://eksisozluk.com/merve-sanayin-pizzaciya-kapiyi-ciplak-acmasi--5868043?a=popular",
"https://eksisozluk.com/merve-sanayin-pizzaciya-kapiyi-ciplak-acmasi--5868043?a=popular");
for ($i = 0; $i < count($arr); $i++)
{
$arr[$i] = substr($arr[$i], 0, 36);
}

Remove characters from Array values

Thanks guys.
I've been towing over this one for over a day now and it's just too difficult for me! I'm trying to remove the last 3 characters from each value within an array. Currently, I've tried converting to a string, then doing the action, then moving into a new array... can't get anything to work. Someone suggested this, but it doesn't work. I need an array of postcodes, "EC1 2AY, EC3 4XW..." converting to "EC1, EC3, ..." and it be back in an Array!!
implode(" ",array_map(function($v){ return ucwords(substr($v, 0, -3)); },
array_keys($area_elements)));
This hasn't worked, and obviously when I converted to a string and do a trim function, it will only take the last 3 characters from the last "variable" in the string.
Please send HELP!
If you want an array back, you shouldn't implode. You are almost there:
$area_elements = ['EC1 2AY', 'EC3 4XW'];
$result = array_map(function($v){
return trim(substr($v, 0, -3));
}, $area_elements);
var_dump($result);
Output:
array(2) {
[0]=>
string(3) "EC1"
[1]=>
string(3) "EC3"
}
Another solution:
altering array by reference.
Snippet
$area_elements = ['EC1 2AY', 'EC3 4XW'];
foreach($area_elements as &$v){
$v = substr($v, 0, -4);
}
print_r($area_elements);
Output
Array
(
[0] => EC1
[1] => EC3
)
Live demo
Pass by reference docs

PHP array containing 0/

hi I have array of elements containing pattern like
$arr = array ('0/' ,'0/12/3','1/2')
i need to have array of "0/" elements i've tried to use command
arr_with_zero_slash = preg_grep('#$[0-9]/$#',$arr)
but function works only witch pattern like 1/ , 2/ and so one. This is because 0/ is treated as special sign but i dont know how to deal with that. Any ideas?
I think this is what you mean:
Cycle through array $arr using a foreach-loop, and unset (remove) all elements that don't start with '0/'...
$arr = array ('0/' ,'0/12/3','1/2');
foreach($arr as $key=>$value){
if(substr($value,0,2)<>"0/"){
unset($arr[$key]);
}
}
With:
$arr = array ('0/' ,'0/12/3','1/2')
this will be the outcome:
array(2) { [0]=> string(2) "0/" [1]=> string(6) "0/12/3" }
If you want to get all elements starting with 0/ try this:
<?php
$arr = array ('0/' ,'0/12/3','1/2', '1/0/4');
$arr_with_zero_slash = preg_grep('#^0/#',$arr);
print_r($arr_with_zero_slash);
This will output
Array (
[0] => 0/
[1] => 0/12/3
)
Removed the first $ since it's a meta-character.
Changed [0-9] to 0, since you only want 0/ and not 1/, 2/ etc.
Removed the second $ since you also want 0/12/3.

Add or modify part of an array as a mysql string

I currently have a column in mysql database that stores a string with delimiters so I can convert it into an array in php.
An example string looks like this:
23,1,1|72,2,0|16,3,1|...etc.
It essentially divides it into 3 major groups with |, and 3 smaller ones with , (if there's a cleaner way, let me know):
1st number is an ID number for an article from a different table
2nd is just a number for indenting purposes
3rd is for visible or not (0 or 1).
I will have an admin section where we'll be able to re-order the major groups (i.e., move group 3 to position 2) and modify specific numbers from the sub-groups (e.g. change 72,1,0 to 72,2,0) I'm not sure how I can accomplish this.
How do I loop through these modifications while keeping the order (or new order) when reinserting into the database?
I was thinking of adding a another number to my string that would determine the position of each major group? Something like this:
1[23,1,1]2[72,2,0]3[16,3,1]
But how do I loop through this and move things around?
Any help would be greatly appreciated.
I agree with the comments about normalization, but if you insist on doing it this way, or are stuck with an existing schema you cannot alter, use the PHP serialize/unserialize functions if you can, rather than string parsing. This will at least allow you to retrieve the data into PHP and modify the array and then save it back.
http://php.net/manual/en/function.serialize.php
I'm joining all comments about the approach used to store data, but nevertheless.
This what can help you to move forward:
/** #var string $s Assumed packet */
$s = "23,3,1|72,1,0|16,2,1"; // Indent is not ordered
/** #var array $parsed Parsed packet */
$parsed = array_map(function ($segment) {
list($artId, $indent, $visibility) = explode(',', $segment);
return [
'ArticleId' => (int)$artId,
'Indent' => (int)$indent,
'Visible' => (int)$visibility !== 0
];
}, explode('|', $s));
usort($parsed, function (array $a, array $b) {
return ($a['Indent'] < $b['Indent']) ? -1 : 1;
});
You'll get following $parsed structure sorted by Indent key:
array(3) {
[0] => array(3) {
["ArticleId"]=> int(23)
["Indent"]=> int(1)
["Visible"]=> bool(true)
}
[1] => array(3) {
["ArticleId"]=> int(72)
["Indent"]=> int(2)
["Visible"]=> bool(false)
}
[2] => array(3) {
["ArticleId"]=> int(16)
["Indent"]=> int(3)
["Visible"]=> bool(true)
}
}
Thus you can alter Indent as you want just applying usort() before/after parsing.
Regarding storing this structure in database the way you decided, you can use JSON format (json_encode(),json_decode()). Such "serialization" way faster than proposed serialize() method and way more faster than $parsed approach + more readable. If you worry about redundancy you can json_encode() array without array keys and add them on parsing or use directly [0], [1], [2] knowing the correspondence beforehand.
If you use json_*() functions you can omit structure parsing bec. it will be decoded right the same you've encoded it for saving. Order can be defined on save using same usort(). This can be considered as improvement by reducing excessive sorts bec. readings/decodings will occur more frequently than saves.
I was interested with your question. So i create this. It may not like what you desired.
<?php
$string = "23,1,1|72,2,0|16,3,1|";
$explode = explode("|", $string);
$a = array();
for($x = 0;$x<count($explode)-1;$x++)
{
$a[] = $explode[$x];
$b[] =explode(',',substr($explode[$x], strpos($explode[$x], ",") + 1));
}
for($y=0;$y<count($b);$y++){
echo $b[$y][0]. '=>'. $a[$y] . '<br>';
}
?>

PHP unset vs array_pop?

If I want to remove the last element of an array, I can use either of these two code:
array_pop($array); (the return value is not used)
unset($array[count($array) -1]);
Is there any performance or semantic difference between them?
If not, which is preferred?
unset is no good if you need to "do" anything with the removed value (unless you have previously assigned it to something elsewhere) as it does not return anything, whereas array_pop will give you the thing that was the last item.
The unset option you have provided may be marginally less performant since you are counting the length of the array and performing some math on it, but I expect the difference, if any, is negligible.
As others have said, the above is true if your array is numerical and contiguous, however if you array is not structured like this, stuff gets complicated
For example:
<?php
$pop = $unset = array(
1 => "a",
3 => "b",
0 => "c"
);
array_pop($pop);
// array looks like this:
// 1 => "a", 3 => "b"
$count = count($unset) - 1;
unset($count);
// array looks like this because there is no item with index "2"
// 1 => "a", 3 => "b", 0 => "c"
array_pop($array) removes the last element of $array.
unset($array[count($array) -1]); removes the element at index count($array) -1. This element is not neccesarily the last element of the array.
Consider $array = array(0 => 'foo', 2 => 'bar', 1 => 'baz'). In this case , $array[1] is the last element. The code
foreach (array(0 => "foo", 2 => "bar", 1 => "baz") as $key => $value)
echo "$key => $value\n";
prints
0 => foo
2 => bar
1 => baz
Moreover, an element at index count($array) -1 might not even exist. There can be gaps in the set of indices and integer indices can be mixed with string indices.
The return values are different. array_pop returns the last element, while unset doesn't return anything.
For simply removing the last element, array_pop would be better because you don't need to execute count($array)-1, and it is cleaner and more readable.
Yes there is.
Firstly, the unset() option will only work for numerical, contiguous arrays. If your array contains elements that are not numerical, or has any gaps in its numerical sequence, then the unset() call will get the incorrect value from count() and will fail.
Secondly, assuming your array is numerical and contiguous, there is still a difference:
array_pop() will also give you back the value of the popped element as a return value. unset() will not do this.
So if you need to keep using the data, use array_pop().
If you don't need to keep the value, then no, it probably doesn't matter too much which one you use, I suspect that array_pop() may be faster (due to not needing to call count()), but I haven't checked, and to be honest, unless you're doing thousands of calls, the difference will be negligible anyway.
Except for the obvious differences in call syntax and return value...
array_pop always pops whatever is last.
Your count - 1 unsets an element by its numeric id, which only works as you expect it to if all elements are continuously numerically indexed.
For what it's worth, using a bit of existing code that gets called a bit over 2000 times in a run, I put in a $whatevers[]=$whatever (a parameter value) at the top and and array_pop($whatevers) at the bottom.
The function calls itself recursively down to about 7 or 8 levels and (of course) I made $whatevers static so the array grew and shrunk.
The result? The difference between this code in and commented out was unmeasurable down to 100ths of a second on a windows 7 laptop. It varied a fair bit because of other things, but over lots of runs the difference in the averages was meaningless.
The performance overhead of array_pop() just isn't worth a second thought and though unset might be theoretically faster, nobody will ever be able to detect the difference.
As others have mentioned - their functionality is the same, bar the return value from array_pop. However, it's also worth mentioning the possible performance issue of the unset method on a large array due to the count() call.
As Oswald mentions, it is also worth noting that unset() will only be working as expected on numeric keys.
Yes there is a difference
array_pop() will also return removed element eg: last element, and
unset() will not return any thing
I would prefer unset() but you call count() which can consume performance.
An alternative choice is array_slice(array, offset, length, preserve_keys) :
$array = array_slice($array, 0, -1, true);
Another consideration to take into account is that if after deleting the last item you push a new element, you get different results in which the index the new element is placed at:
unset
php > $a = [1,2,3];
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
php > unset($a[2]);
php > var_dump($a);
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
php > $a[] = 5;
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[3]=>
int(5)
}
As you see, the new element is placed at index 3 instead of 2.
array_pop
php > $a = [1,2,3];
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
php > array_pop($a);
php > var_dump($a);
array(2) {
[0]=>
int(1)
[1]=>
int(2)
}
php > $a[] = 5;
php > var_dump($a);
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(5)
}
Now the new element is placed at index 2. Maybe this is the most desirable behaviour.

Categories