How to get this element from this array - php

I have an array $arr that when I var_dump looks like this. What's the easiest way to get the 2nd last item ('simple' in this case). I can't do $arr[4] because the number of items may vary per url, and I always want just the 2nd last. (note that there's an extra empty string at the end, which will always be there.)
array
0 => string 'http:' (length=5)
1 => string '' (length=0)
2 => string 'site.com'
3 => string 'group'
4 => string 'simple'
5 => string 'some-test-url'
6 => string '' (length=0)

So long as it is not a keyed or hashed array and it has more than two items...
$arr[count($arr) - 2];
Note: that my interpretation of second to last is second from the end. This may differ from yours. If so, subtract 3.

Get the count and subtract 3?
$arr[count($arr)-3]

if (!empty($arr) && count($arr)>1){
//or > 2, -3 for your extra ending
$val = $arr[count($arr)-2];
}
Should help you.

$second_last = count($array) - 3;
$value = $array[$second_last];

$arrayLen=count($arr);
echo $arr[$arrayLen-2];

Yet another alternative:
echo current(array_slice($data, -3, 1));

Related

Explode string with two different separators to create multidimensional array

I have a string:
01;Tommy;32;Coder&&02;Annie;20;Seller
I want it like this:
array (size=2)
0 =>
array (size=4)
0 => string '01' (length=2)
1 => string 'Tommy' (length=5)
2 => int 42
3 => string 'Coder' (length=5)
1 =>
array (size=4)
0 => string '02' (length=2)
1 => string 'Annie' (length=5)
2 => int 20
3 => string 'Seller' (length=6)
Hope you can help me, thank you!
Not sure if the datatypes will be matching (as I believe it's all in a string) but here's the code
$myarray = array();
foreach(explode("&&",$mystring) as $key=>$val)
{
$myarray[] = explode(";",$val);
}
The explode command takes a string and turns it into an array based on a certain 'split key' which is && in your case
but since this is a dual array, I had to pass it through a foreach and another explode to solve.
It's very simple. First you need to explode the string by && and then traverse through array exploded by &&. And explode each element of an array by ;.
Like this,
<?php
$str="01;Tommy;32;Coder&&02;Annie;20;Seller";
$array=explode("&&",$str);
foreach($array as $key=>$val){
$array[$key]=explode(";",$val);
}
print_r($array);
Demo: https://eval.in/629507
you should just have to split on '&&', then split the results by ';' to create your new two dimensional array:
// $string = '01;Tommy;32;Coder&&02;Annie;20;Seller';
// declare output
$output = [];
// create array of item strings
$itemarray = explode('&&',$string);
// loop through item strings
foreach($itemarray as $itemstring) {
// create array of item values
$subarray = explode(';',$itemstring);
// cast age to int
$subarray[2] = (int) $subarray[2]; // only useful for validation
// push subarray onto output array
$output[] = $subarray;
}
// $output = [['01','Tommy',32,'Coder'],['02','Annie',20,'Seller']];
keep in mind that since php variables are not typed, casting of strings to ints or keeping ints as strings will only last depending on how the values are used, however variable type casting can help validate data and keep the wrong kind of values out of your objects.
good luck!
There is another appropach of solving this problem. Here I used array_map() with anonymous function:
$string = '01;Tommy;32;Coder&&02;Annie;20;Seller';
$result = array_map(function($value){return explode(';',$value);}, explode('&&', $string));

Closest value of an array below a reference value

I have an array that contains time stamps with associated "left" or "right" values:
array (size=237)
1421439428 => string 'left' (length=4)
1421439411 => string 'right' (length=5)
1421439392 => string 'left' (length=4)
[here goes the example TS from below]
1421439380 => string 'right' (length=5)
1421439358 => string 'left' (length=4)
1421439329 => string 'right' (length=5)
1421439240 => string 'right' (length=5)
1421439234 => string 'left' (length=4)
Now I want to give a time stamp, e.g. 1421439391 (that is or is not in the keys) and I want to know, what is the most recent value. In this case "right". Even if it is closer to the left value I want to know the value below!
How is that possible (without a loop)?
With loop (based on function linked by Alex W):
function closest($array, $number) {
foreach ($array as $key=>$val) {
if ($key <= $number) return $val;
}
return end($array); // or return NULL;
}
Obviously, to make this as efficient as possible you're going to first want to sort the array by the timestamps. Then, you will need to write your own closest function like this one.
Since you say you don't want to use a loop, which is how you would normally do it, you'll have to implement some kind of hashing function for the array indices that keeps the array sorted by timestamp value. Then, you can insert the timestamp value if it doesn't exist and then go to the next array index.

How to get next value in a multidimensional array

I am trying to produce a HTML list grouped by "groupName" from the array below.
array (size=30)
0 =>
array (size=4)
'groupOrder' => string '1' (length=1)
'groupName' => string 'Class' (length=11)
'txt' => string '............' (length=32)
'ID' => string '6' (length=1)
1 =>
array (size=4)
'groupOrder' => string '1' (length=1)
'groupName' => string 'Size' (length=11)
'txt' => string '..................' (length=34)
'ID' => string '6' (length=1)
2 =>
...
So I'd like produce something like this pseudo list:
groupName
txt
txt
txt
next GroupName
txt
txt
...
So my code looks like this
foreach ($datafeed as $val => $row) {
if (($datafeed[$val]['groupName']) == next($datafeed[$val]['groupName'])) {
//same group - do nothing
} else {
echo $datafeed[$val]['groupName'];
}
echo "<li>".$row['txt']. "</li>";
}
But I'm getting errors about "next() expects parameter 1 to be array, string given".
I've tried all sorts of different syntax, but I'm not making much progress. How do I compare two values in a nested array?
You misinterpreted the meaning of the function next(): you cannot query it for an array element. It manipulates the internal array pointer tied with the array itself, not with some its element. From the PHP documentation:
Every array has an internal pointer to its "current" element, which is initialized to the first element inserted into the array.
and see also a description of next.
Since the foreach loop crucially depends on the value of the array pointer, messing with the array pointer will ruin the loop: you probably see every second element in the loop, because at every iteration once next() is called by your foreach loop and then once by yourself.
The simplest thing for you is probably to use the old good for loop:
for ($i = 0; $i < length ($array); $i++)
{
if ($i == 0 || $array[$i] != $array[$i - 1])
echo "New group!\n";
echo $array[$i];
}
This doesn't answer your question directly, but you'd be better off restructuring your array so that they're grouped, and you don't need to perform any logic within the loop to check the groupName. Currently, you're relying on the next groupName to match the current groupName, but if they're not sequential, they won't be grouped.
You could do something like this:
$output = array();
foreach ($datafeed as $feed) {
$output[$feed['groupName']][] = $feed;
}
Here's a demo
You should not use next inside a foreach loop anyway, since you'll get conflicting array pointer movements. Simply store the last value:
$last = null;
foreach (...) {
if ($last != $row['current']) {
// new group
}
$last = $row['current'];
...
}

Does not equal performing opposite in a foreach loop

I have an array that looks something like
array (size=7)
'car_make' => string 'BMW' (length=3)
'car_model' => string 'M3' (length=2)
'car_year' => string '2001' (length=4)
'car_price' => string '10000' (length=5)
'car_kilometers' => string '100000' (length=6)
'paint' => string 'black' (length=5)
'tires' => string 'pirelli' (length=7)
So basically there are a few base items in it that start with car_ and then a few extras.
I'm trying to search for each key that isn't car_* so paint and tires in this case. So I'm doing something like
foreach($_SESSION['car'][0] as $key=>$value)
{
if($key != preg_match('/car_.*/', $key))
{
echo 'Match';
}
}
Which I expected to echo out 2 Matches because of the 2 non car_ keys. Instead, this echos out 5 for the car_ keys.
But when I do
if($key == preg_match('/car_.*/', $key))
It echoes out 2 Matches for the 2 non car_ keys.
Where am I messing up or misunderstanding?
preg_match docs say about its return values:
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
So this wouldn't have worked in the first place.
I would use:
if ( substr($key, 0, 4) === "car_" )
...which is much less expensive as an operation than preg_match anyway.
According the documentation preg_match returns true when matching and false when not. So it appears that you are having some fun with PHP's type casting.
So rather than comparing the value you should check
if(true === preg_match('/car_.*/', $key))
This should take care of it.
Also, per the documentation:
Do not use preg_match() if you only want to check if one string is
contained in another string. Use strpos() or strstr() instead as they
will be faster.
Which would be:
if(false === str_pos('car_', $key))
From http://php.net/manual/en/function.preg-match.php
Return Values
preg_match() returns 1 if the pattern matches given subject, 0 if it
does not, or FALSE if an error occurred.
So you should compare it to 1 or to 0, not to a string.
The reason why your code was working but backwards is because comparing a number to a string produces interesting results:
From http://php.net/manual/en/types.comparisons.php
1 == "" is FALSE
0 == "" is TRUE

How to split an array by every nth appearance of a string?

This question is different to Split, a string, at every nth position, with PHP, in that I want to split a string like the following:
foo|foo|foo|foo|foo|foo
Into this (every 2nd |):
array (3) {
0 => 'foo|foo',
1 => 'foo|foo',
2 => 'foo|foo'
}
So, basically, I want a function similar to explode() (I really doubt that what I'm asking will be built-in), but which 'explodes' at every nth appearance of a certain string.
How is this possible?
You can use explode + array_chunk + array_map + implode
$string = "foo|foo|foo|foo|foo|foo";
$array = stringSplit($string,"|",2);
var_dump($array);
Output
array
0 => string 'foo|foo' (length=7)
1 => string 'foo|foo' (length=7)
2 => string 'foo|foo' (length=7)
Function used
function stringSplit($string, $search, $chunck) {
return array_map(function($var)use($search){return implode($search, $var); },array_chunk(explode($search, $string),$chunck));
}

Categories