Remove everything before the dash from a Laravel array - arrays

I have a Laravel array and would like to modify the returned values.
$array = ['hr-34', 've-53', 'dv-65'];
I want to remove everything before the dash and the dash itself and return the following array.
$array = ['34', '53', '65'];

You can do something like this:
foreach ($c as $key => $value) {
$pieces = explode('-', $value);
$array[$key] = $pieces[1];
}
You have used the tag collections. So if it's a collection you can use this function:
$c->map(function ($item) {
return explode('-', $item)[1];
})

Steps to follow:
define blank array $new_array (to fill single value from foreach loop).
get single value using foreach loop.
use strstr for remove everything before dash and remove '-' using str_replace.
fill single value in $new_array.
return $new_array outside foreach loop.
Below is the code -
$array = ['hr-34', 've-53', 'dv-65'];
$new_array = array();
foreach($array as $key=>$result){
$data = str_replace('-', '', strstr($result, '-'));
$new_array[]= $data;
}
print_r($new_array);
That's all!

https://www.php.net/manual/en/function.array-map.php
https://www.php.net/manual/en/function.explode.php
$array = array_map(function ($item) {
return explode('-', $item)[1];
}, $array)
Edit:
As you changed title from array to collection you can use:
https://laravel.com/docs/9.x/collections#method-map
$collection->map(...)
in a similar way to array_map(...)

$array = ['hr-34', 've-53', 'dv-65'];
$array = collect($array)
->map(fn($item) => explode('-', $item)[1])
->all();
/**
* array:3 [
* 0 => "34"
* 1 => "53"
* 2 => "65"
* ]
*/
dd($array);
Here this code in sandbox

you can use regex with preg_replace as :
$new = array_map(function ($item) {
return preg_replace('/^([^-])+-/', '', $item);
}, $array);
result :
array:3 [
0 => "34"
1 => "53"
2 => "65"
]

Related

Get array object data from exploded array fields in foreach loop

I'm trying to extract data from our JSON data based on given output fields, but I'm not getting a good result.
e.g.
Given fields that I want:
Array
(
[0] => id
[1] => name
[2] => email
[3] => optin_email
)
Those fields exist in my datastring, I want to export those to a CSV.
I can do this, hardcoded
foreach ($jsonString as $value) {
$row = [
$value->id,
$value->name,
$value->email,
$value->phone
];
print_r($row);
}
The above will give me the list/file I need. BUT, I want to make that dynamic based on the data in the array, so, fo rexample, when this is the Array:
Array
(
[0] => id
[1] => name
)
This should be my output:
foreach ($jsonString as $value) {
$row = [
$value->id,
$value->name
];
print_r($row);
}
So I need to dynamicly create the
$value->{var}
I have been trying forever, but I am not seeing it straight anymore.
Tried this:
$rowFields = '';
foreach ($export_datafields AS $v) {
$rowFields .= '$value->' . $v . ',';
}
$trimmed_row_fields = rtrim($rowFields, ',');
foreach ($jsonString as $value) {
$row = $trimmed_row_fields;
print_r($row);
}
And several variations of that:
foreach ($jsonString as $value) {
$row = [$trimmed_row_fields];
print_r($row);
}
Question is: how can I get
$value->VAR
as a valid array key when I only know the VAR name and need the prefixed $value-> object.
I ended up using the following code which works for me. If anybody still has the answer to my original question, please shoot. Always good to know it all.
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=$csvFileName");
header("Pragma: no-cache");
header("Expires: 0");
$new_row = implode(",", $export_datafields) . "\n";
foreach ($jsonString as $value) {
foreach ($export_datafields AS $v) {
$new_row .= $value->$v . ',';
}
$new_row = substr($new_row, 0, -1);
$new_row .= "\n";
}
echo $new_row;

How to pass multi-dimensional arrays through url as query parameters? and access these parameters in laravel 6.0

I am trying to pass a multi-dimensional array as a query parameter in the below URL:
{{serverURL}}/api/v1/classes?with[]=section.courseteacher&addl_slug_params[0][0]=test&addl_slug_params[0][1]=test1&addl_slug_params[0][2]=test0
what is wrong with the above URL?
My code to access these parameters in Laravel 6.0 is below:
$addl_slug_params = $request->query('addl_slug_params');
$i=0;
foreach ($addl_slug_params as $s) {
$j=0;
foreach($s as $asp) {
print_r('addl_slug_params : ('.$i.':'.$j.') : '.$asp); die();
$j=$j+1;
}
$i = $i+1;
}
Result:
addl_slug_params : (0:0) : test
Problem: test1 and test0 are not accessible..
What should I do?
The problem is the die(); after printr(), the loop will run once, aka only addl_slug_params : (0:0) : test
To help you visualize it better, I added an extra break after each loop:
foreach ($addl_slug_params as $s) {
$j=0;
foreach($s as $asp) {
echo('addl_slug_params : ('.$i.':'.$j.') : '.$asp);
echo nl2br(PHP_EOL);
$j=$j+1;
}
$i = $i+1;
}
Will result in the following:
addl_slug_params : (0:0) : test
addl_slug_params : (0:1) : test1
addl_slug_params : (0:2) : test0
here is a solution for multi-dimensional arrays. Developed in 2~ hours, definitely needs improvement but hopefully helps you out :)
Route::get('example', function (\Illuminate\Http\Request $request) {
$addl_slug_params = [
[
1 => [
'title' => 'Test 1',
'slug' => 'test1'
],
2 => [
'title' => 'Test 2',
'slug' => 'test2'
],
3 => [
'title' => 'Test 3',
'slug' => 'test3'
],
],
];
// Encode
$prepend = 'addl_slug_params';
$query = "?$prepend";
$tempSlugs = $addl_slug_params[0];
$lastIndex = count($tempSlugs);
foreach ($addl_slug_params as $pIndex => $params) {
foreach ($params as $sIndex => $slugData) {
$tempQuery = [];
foreach ($slugData as $sdIndex => $data) {
// Replace '-' or ' -' with ''
$encodedString = preg_replace('#[ -]+#', '-', $data);
// title = test1
$tempString = "$sdIndex=$encodedString";
$tempQuery[] = $tempString;
}
$dataQuery = implode(',', $tempQuery);
$appendStr = ($sIndex !== $lastIndex) ? "&$prepend" : '';
// Set the multidimensional structure here
$query .= "[$pIndex][$sIndex]=[$dataQuery]$appendStr";
}
}
// DECODE
// ?addl_slug_params[0][1]=[title=Test-1,slug=test1]&addl_slug_params[0][2]=[title=Test-2,slug=test2]&addl_slug_params[0][3]=[title=Test-3,slug=test3]
$slugParams = $request->query('addl_slug_params');
$slugParamData = [];
foreach ($slugParams as $slugItems) {
foreach ($slugItems as $slugItem) {
// Replace [title=test,slug=test1] into 'title=test,slug=test1' and explode
// into into an array, and split title=test into [title => test]
$splitArray = explode(',', (str_replace(array('[', ']'), '', $slugItem)));
$slugItemData = [];
foreach ($splitArray as $value) {
$data = explode('=', $value);
$slugItemData[$data[0]] = $data[1];
}
$slugParamData[] = $slugItemData;
}
}
dd($slugParamData);
});
I have solved the problem using associative arrays as it gives more flexibility and Garrett's solution definitely helped
new url: {{serverURL}}/api/v1/classes?with[]=section.courseteacher&addl[users][params]=name
laravel code:
`
foreach ($addl_data_array as $addl_slug => $addl_slug_data) {
foreach ($addl_slug_data as $key => $value) {
$params = null;
$where_raw = null;
$where_has = null;
$with_relationships = null;
$with_timestamps = null;
}
}
`

SilverStripe 3.1 loop associative array

In SilverStripe 3.1 I have a function that loops through an array and outputs its contents.
The output it gives me is:
Layout: John
Strategy: John
Management: Martin
In this example John has more than one job.
I would like to group the jobs if a person has more than one job.
This is my desired Output:
Layout and Strategy: John
Management: Martin
//$InfoFieldArray = array('Layout' => 'John', 'Strategy' => 'John', 'Management' => 'Martin');
public function createInfoFields($InfoFieldArray){
$Info = ArrayList::create();
foreach($InfoFieldArray as $key => $value ){
$fields = new ArrayData(array('FieldName' => $key, 'Value' => $value));
$Info->push($fields);
}
return $Info;
}
How do I alter my function to achieve my desired output?
One possible solution to that is by restructuring the data before adding it to the ArrayList.
public function createInfoFields($InfoFieldArray)
{
$info = array();
foreach ($InfoFieldArray as $job => $person)
{
if (!isset($info[$person]))
{
$info[$person] = array();
}
$info[$person][] = $job;
}
$result = ArrayList::create();
foreach ($info as $person => $jobs)
{
$fields = new ArrayData(array('FieldName' => implode(' and ', $jobs), 'Value' => $person));
$result->push($fields);
}
return $result;
}
What I have done is go over the array of jobs and the person assigned and flipped it the other way around, so I have an array of people with a list of jobs. This allows me to then just call implode in PHP, joining the various jobs by the word and.
There are some potential drawbacks, if there are two people named "John", they will be treated as one as I am using the name as the array key.
Also, if there are three jobs for a person, it will list it like "Layout and Strategy and Management". To avoid that, we need to modify the second foreach loop in my code to something like this:
foreach ($info as $person => $jobs)
{
$jobString = null;
if (count($jobs) > 1)
{
$jobString = implode(', ', array_slice($jobs, 0, -1)) . ' and ' . array_pop($jobs);
}
else
{
$jobString = $jobs[0];
}
$fields = new ArrayData(array('FieldName' => $jobString, 'Value' => $person));
$result->push($fields);
}
When there is more than 1 job for a person, we want to implode (glue together) the array pieces for the $jobs array however we don't want the last element at this point. Once array is glued together, we append with with and along with the last item.

Strange behaviour of Perl's push function

I am writing a dedicated ICS (iCalendar file) parser.
I pass an array to a subroutine. All variables are single values apart from $notdates which is a comma-separated list of dates.
#entryl = ($dtstart, $dtend, $attendee, $lastmod, $uid, $notdates);
&entrytoarray(#entryl);
sub entrytoarray {
# print Dumper #_;
my $shiftdur = (&stamptoepoc($_[1]) - &stamptoepoc($_[0])) / 60 / 60;
my $attendee = $_[2];
my $deleted = $_[5];
$attendee =~ /ATTENDEE;USER-KEY=([^;]*);CN=([^;]*);.*:(.*)/;
my %ehash = (
"STARTDATE" , &stamptodate($_[0]),
"ENDDATE" , &stamptodate($_[1]),
"STARTSTAMP" , $_[0],
"ENDSTAMP" , $_[1],
"USERKEY" , $1,
"CN" , $2,
"EMAIL" , $3,
"LASTMOD" , $_[3],
"UID" , $_[4],
"DURATION" , $shiftdur
);
# Only keep current data
my $fdays = 4;
my $tdays = 7;
chomp(my $curstamp = `TZ="UTC" date -d "$fdays days" +"%Y%m%d%H%M00"`);
chomp(my $stpstamp = `TZ="UTC" date -d "$tdays days" +"%Y%m%d%H%M00"`);
if (($_[0] > $curstamp) && ($_[1] < $stpstamp)) {
if (defined($deleted)) {
my #deleted = split /,/, $deleted;
foreach (#deleted) {
if ($_ ne $_[0]) {
push(#entry, \%ehash);
}
}
}
else {
push(#entry, \%ehash);
}
}
print Dumper #entry;
This works mostly as expected:
$VAR1 = {
'DURATION' => '5',
'STARTSTAMP' => '20141122230000',
'UID' => '20141114T010539Z--1092363482',
'LASTMOD' => '20141118214419',
'STARTDATE' => '2014-11-22 23:00:00',
'EMAIL' => 'xxxxxxxxxxxxx',
'ENDDATE' => '2014-11-23 04:00:00',
'CN' => 'xxxxxxxxxxx',
'ENDSTAMP' => '20141123040000',
'KEY' => 'xxxxxxxxxxxxxxxxxx'
};
$VAR2 = {
'EMAIL' => 'xxxxxxxxxxxxx',
'ENDDATE' => '2014-11-23 23:00:00',
'ENDSTAMP' => '20141123230000',
'KEY' => 'xxxxxxxxxxx',
'CN' => 'xxxxxxxxxxxxxx',
'STARTDATE' => '2014-11-23 19:00:00',
'LASTMOD' => '20141118205901',
'UID' => '20141114T010456Z--1092363482',
'DURATION' => '4',
'STARTSTAMP' => '20141123190000'
};
$VAR3 = $VAR2;
Where is the $VAR3 = $VAR2 coming from?
My guess is that this section is the culprit:
foreach (#deleted) {
if ($_ ne $_[0]) {
push(#entry, \%ehash);
}
}
If you have several values in the array, the if-statement can be true twice, and thus push a value twice. Unless this is wanted behaviour, I would make sure that only one value is pushed. You can do this by using grep instead:
if (grep { $_ ne $_[0] } #deleted) {
push #entry, \%ehash;
}
Note that this replaces the foreach loop.
Your array #entry contains hash references. Data::Dumper is saying that the first and second elements of the array refer to two different hashes, while the third refers to the same hash as the second.
You don't show where #entry comes from, but I would expect all three elements to be references to %ehash.
The problem is that, if you keep pushing a reference to %ehash onto #entry, they all point to the same data item, and the intermediate states of the hash won't be recorded.
Unless you mean entrytoarray to push only one copy of %ehash (in which case there's a separate problem that we can't see) you need to fix it by either writing
push #entry, { %ehash }
which copies the hash and returns a reference to the copy, or you can declare and populate %ehash inside the foreach loop, which will create a new hash each time around the loop.

Get comma seperated values from PHP array

Do we have any array function in PHP to get this:
// get all the user ids as comma seprated.
$users = array();
foreach($view as $result)
{
$users[] = $result->uid;
}
$uid = implode(',', $users);
Example:
$array[0] = array("size" => "XL", "color" => "gold");
$array[1] = array("size" => "XLL", "color" => "siver");
$array[2] = array("size" => "M", "color" => "purple");
I need
$color = "gold,silver,purple";
Thanks in Advance for your help.
You can use explode(',', $view) in order to get the values array.
From your updated question:
You could try something like this:
'firstname_value','lastname'=>'lastname_value');
sprintf('INSERT INTO %s (%s) VALUES ("%s")', 'table_name', implode(', ', array_map('mysql_escape_string', array_keys($values))), implode('", "',array_map('mysql_escape_string', $values)));
//that gives you: INSERT INTO table_name (firstname, lastname) VALUES ("firstname_value", "lastname_value")
?>

Resources