Comma separated list from array [duplicate] - php

This question already has answers here:
Create a comma-separated string from a single column of an array of objects
(15 answers)
Closed 7 months ago.
I am wondering how to:
Make comma-separated list
Strip last comma from list
Here's an array example:
Array
(
[name] => Array
(
[0] => Some message to display1
)
[test] => Array
(
[0] => Some message to display2
)
[kudos] => Array
(
[0] => Some message to display3
)
)
I want to display it like this:
Comma-List: Some message to display1, Some message to display2, Some message to display3

Loop through the arrays and implode() after you've got each array.
$bigArray = array();
foreach($firstArray as $secondArray){
if(is_array($secondArray)){
$bigArray = array_merge($bigArray, $secondArray);
}
}
$commaList = implode(",", $bigArray);

so, revising my answer to actually address your question, you could do it with nested foreach loops like this:
<?php
$a1 = array(
'name' => array( 0 => 'Some message to display1'),
'test' => array( 0 => 'Some message to display2'),
'kudos' => array( 0 => 'Some message to display3'),
);
$final = "";
foreach($a1 as $innerarray){
foreach($innerarray as $message){
$final .= $message.", ";
}
}
echo substr($final,0,-2);
?>

You can use implode to join values and array_map to extract them:
// this should be your array
$youArray = array();
// return first elements
$values = array_map(function($item) { return $item[0]; }, $youArray);
// echo joined values
echo implode(',', $values);

$array = array("some text","other text");
$impl = implode(",", $array);
echo $impl;

implode works on 1D arrays, but you have a 2D array, this will take a bit more work.
You can use array_map to flatten the array
$flatArray = array_map(function($a){
// I implode here just in case the arrays
// have more than one element, if it's just one
// you can return '$a[0];' instead
return implode(',', $a);
}, $array);
echo implode(',', $flatArray);

This works for your array and should work for arrays that are n levels deep:
$array = array(
'name' => array('Some message to display1'),
'test' => array('Some message to display2'),
'kudos' => array('Some message to display3')
);
$mystr = multi_join($array);
while (substr($mystr, -1) == ',') {
$mystr = substr($mystr, 0, -1);
}
echo $mystr;
function multi_join($value) {
$string = '';
if (is_array($value)) {
foreach ($value as $el) {
$string.= multi_join($el);
}
} else {
$string.= $value.',';
}
return $string;
}

Simplest for your specific sample data would be to access the 0 column of data and implode that. (Demo)
echo implode(', ', array_column($array, 0));
Here are a couple of additional techniques to add to this heap...
Reindex the first level because the splat operator doesn't like associative keys, then merge the unpacked subarrays, and implode.
Use array_reduce() to iterate the first level and extract the first element from each subarray, delimiting as desired without the use of implode().
Codes: (Demo)
$array = [
'name' => ['Some message to display1'],
'test' => ['Some message to display2'],
'kudos' => ['Some message to display3']
];
echo implode(', ', array_merge(...array_values($array)));
echo "\n---\n";
echo array_reduce($array, function($carry, $item) {return $carry .= ($carry ? ', ' : '') . $item[0]; }, '');
Output:
Some message to display1, Some message to display2, Some message to display3
---
Some message to display1, Some message to display2, Some message to display3
The first technique will accommodate multiple elements in the subarrays, the second will not acknowledge more than one "message" per subarray.

Related

How to check if two strings have the same beginning?

Considering I have one-dimensional ordered array of strings:
$arr = [
'Something else',
'This is option: one',
'This is option: two',
'This is option: 😜',
'This is second option: 2',
'This is second option: 3'
];
I would like to turn it into two-dimensional array, having the common beginning as the key. For example:
$target = [
'Something else',
'This is option:' => [
'one',
'two',
'😜'
],
'This is second option:' => [
'2',
'3'
]
];
It sounds simple, but I have gone completely blank.
function convertArr(array $src): array {
$prevString = null;
$newArray = [];
foreach ($src as $string) {
if ($prevString) {
// stuck here
}
$prevString = $string;
}
return $newArray;
}
Pre-made fiddle: https://3v4l.org/eqGDc
How can I check if two strings start with the same words, without having to loop on each letter?
As of now I have written this overly-complicated function, but I wonder if there is a simpler way:
function convertArr(array $src): array {
$prevString = null;
$newArray = [];
$size = count($src);
for ($i = 0; $i < $size; $i++) {
if (!$prevString || strpos($src[$i], $prevString) !== 0) {
if ($i == $size - 1) {
$newArray[] = $src[$i];
break;
}
$nowWords = explode(' ', $src[$i]);
$nextWords = explode(' ', $src[$i + 1]);
foreach ($nowWords as $k => $v) {
if ($v != $nextWords[$k]) {
break;
}
}
if ($k) {
$prevString = implode(' ', array_splice($nowWords, 0, $k));
$newArray[$prevString][] = implode(' ', $nowWords);
}
} else {
$newArray[$prevString][] = trim(substr($src[$i], strlen($prevString)));
}
}
return $newArray;
}
This might do the job:
function convertArray(array $values): array
{
$newArray = [];
foreach ($values as $value) {
if (stripos($value, ':') !== false) {
$key = strtok($value, ':');
$newArray[$key][] = trim(substr($value, stripos($value, ':') + 1));
}
}
return $newArray;
}
Essentially, based on the format of your array of strings, as long as each string only has one ":" character followed by the option value, this should work well enough.
I'm sure there will be a more advanced and more fail-safe solution but this may be a start.
I haven't got a complete solution, but maybe you can use this as a starting point: The following gets you the longest common starting sequence for the strings in an array of length 2:
var s=["This is option: one","This is option: two"];
var same=s.join('|').match(/(.*)(.*?)\|\1.*/)[1];
// same="This is option: "
In same you will find the longest possible beginning of the two strings in array s. I achieve this by using a regular expression with a greedy and a non-greedy wildcard group and forcing the first group to be repeated.
You could apply this method on slice()-d short arrays of your original sorted input array and monitor whether same stays the same for a number of these sub-arrays. You can then perform your intended grouping operation on sections with the same same.
[[ Sorry, I just realized I coded this in JavaScript and you wanted PHP - but the idea is so simple you can translate that easily into PHP yourself. ]]
Edit
When looking at the question and expected result again it seems to me, that what the OP really wants is to combine elements with similar parts before the colon (:) into a common sub-array. This can be done with the following code:
$arr = [
'Is there anything new and',
'Something old',
'This is option: one',
'This is option: two',
'This is option: 😜',
'This is second option: 2',
'This is second option: 3',
'Abc: def',
'Abc: ghi',
'the same line',
'the same words'
];
foreach($arr as $v) {
$t=array_reverse(explode(':',$v));
$target[isset($t[1])?trim($t[1]):0][]=trim($t[0]);
}
print_r($target)
output:
Array
(
[0] => Array
(
[0] => Is there anything new and
[1] => Something old
[2] => the same line
[3] => the same words
)
[This is option] => Array
(
[0] => one
[1] => two
[2] => 😜
)
[This is second option] => Array
(
[0] => 2
[1] => 3
)
[Abc] => Array
(
[0] => def
[1] => ghi
)
)
See a demo here https://rextester.com/JMB6676

PHP Array to string

I am getting array from one of my network devices and I don't understand how I can get output array to string.
I get this array:
Array
(
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.1] => STRING: "sensitive_data_1"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.2] => STRING: "sensitive_data_2"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.3] => STRING: "sensitive_data_3"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.4] => STRING: "sensitive_data_4"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.5] => STRING: "sensitive_data_5"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.6] => STRING: "sensitive_data_6"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.7] => STRING: "sensitive_data_7"
[iso.3.6.1.4.1.12356.101.12.2.4.1.3.8] => STRING: "sensitive_data_8"
)
And I don't know how can I get only sensitive_data_1-8 to my values.
EDIT: I want output like:
$value[1] = "sensitive_data_1";
$value[2] = "sensitive_data_2";
Use array_map() function then substr() to get the portion of array's string value
$array = array(
// Your array data here
);
$value = array_map(function($e) {
return substr($e, 8);
}, $array);
echo $value[0]; // Outputs "sensitive_data_1"
echo $value[1]; // Outputs "sensitive_data_2"
Simple work around if you want to start with $value[1]
$array = array(
// Your array data here
);
$value = array_map(function($e) {
return substr($e, 8);
}, $array);
array_unshift($value, ''); // Add dummy data
unset($value[0]); // Remove dummy data
echo $value[1]; // Outputs: "sensitive_data_1"
echo $value[2]; // Outputs: "sensitive_data_2"

Group subarrays by one column, make comma-separated values from other column within groups

I have a array that looks like this:
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
I need to group as a new array that looks like:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)
I'd tried many scripts, but with no success.
function _group_by($array, $key) {
$return = array();
foreach($array as $val) {
$return[$val[$key]][] = $val;
}
return $return;
}
$newArray = _group_by($array, 1); // (NO SUCCESS)
There should be more elegant solutions, but simplest one I can think of would be this.
// The data you have pasted in the question
$data = [];
$groups = [];
// Go through the entire array $data
foreach($data as $item){
// If the key doesn't exist in the new array yet, add it
if(!array_key_exists($item[1], $groups)){
$groups[$item[1]] = [];
}
// Add the value to the array
$groups[$item[1]][] = $item[0];
}
// Create an array for the data with the structure you requested
$structured = [];
foreach($groups as $group => $values){
// With the array built in the last loop, implode it with a comma
// Also add the 'key' from the last array to it ($group)
$structured[] = [implode(',', $values), $group];
}
I haven't tested this but something similar should do the trick. This simply goes through the given array and collects all entries in a structurized manner (so $groups variable will contain an array entry for each group sharing a key, and the key will correspond to the 2nd item in each item within the given array). From there it's just about restructuring it to get the format you have requested.
http://php.net/manual/en/control-structures.foreach.php
Writing two loops is too much effort for this task. Use isset() with temporary keys applied to your output array as you iterate. When finished grouping the data, reindex the output with array_values().
Code (Demo)
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
foreach ($array as $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row; // first occurrence of group, save whole row
} else {
$result[$row[1]][0] .= ',' . $row[0]; // not first occurrence, concat first element in group
}
}
var_export(array_values($result));
Or avoid the temporary associative arrays in the result array by using an array of references. (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row[1]])) {
$ref[$row[1]] = $row;
$result[] = &$ref[$row[1]];
} else {
$ref[$row[1]][0] .= ',' . $row[0];
}
}
var_export($result);
Or use array_reduce() to enjoy a functional-style technique. (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row;
} else {
$result[$row[1]][0] .= ',' . $row[0];
}
return $result;
}
)
)
);
All will output:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)

Combine two array in php

I have two array in php and now I want to combine this two array as below.
$a1 = Array(
'ansid4' => 4,
'ansid5' => 5,
'ansid6' => 6
);
$a2 = Array(
'value' => 'demo',
'value2' => 'demo2'
);
Required Output:
$target = Array(
4 => 'demo',
5 => 'demo2',
6 => Null
);
Thanks in advance
$resultArray = array();
while ($key = array_pop($arrayOne)) {
$resultArray[$key] = array_pop($arrayTwo);
}
or you could do
$resultArray = array();
foreach ($arrayOne as $key) {
$resultArray[$key] = array_shift($arrayTwo);
}
Both solutions have the disadvantage that they consume one or both arrays.
If you need them still after the combination you could make copies of the Arrays and have those consumed.
Take a look at array_combine
you can send to this function array of keys and array of values and it return assoc array
please notice that the two arrays must have the same number of elements.
if you cant take care of that, try using array_pad before
$targetArray = array('a'=>'','b'=>'');
$sourceArray = array('a'=>array(1,2,3),'c'=>'c','d'=>'d');
$result = array_merge( $targetArray, $sourceArray);
$array_text = recurse_array($result);
echo $array_text;
function recurse_array($values){
$content = '';
if( is_array($values) ){
foreach($values as $key => $value){
if( is_array($value) ){
$content.="$key<br />".recurse_array($value);
}else{
$content.="$key = $value<br />";
}
}
}
return $content;
}
You have to have the same number of elements in both arrays so we start with counting of elements and add necessary NULL values by array_pad
if (count($a1) > count($a2))
{
$a2 = array_pad1($a2, count($a1), NULL);
}
elseif (count($a1) < count($a2))
{
$a1 = array_pad($a1, count($a2), NULL);
}
Then we use array_combine, which creates new array. From both arrays we use values by array_values. From first array we use values as keys and from second array we use values as values:-)
$target = array_combine(array_values($a1), array_values($a2))

Sort array based on number in value

I have an array that looks like this:
Array
(
[0] => ripe#hobby.nl 20140827
[1] => bas#hobby.nl 20130827
[2] => bas#dikkenberg.net 20140825
[3] => bas#hobby.nl 20120825
[4] => ripe#hobby.nl 20140826
)
Now i want to sort this array in php based on the numbers only so ignoring the e-mail adres in the sort process.
For example, assuming entries are always like email space number:
usort($ary, function($a, $b) {
$a = intval(explode(' ', $a)[1]);
$b = intval(explode(' ', $b)[1]);
return $a - $b;
});
or in more complicated but efficient way using Schwartzian transform:
$ary = array_map(function($x) {
return [intval(explode(' ', $x)[1]), $x];
}, $ary);
sort($ary);
$ary = array_map(function($x) {
return $x[1];
}, $ary);
<?php
$data = Array(0 => 'ripe#hobby.nl 20140827',
1 => 'bas#hobby.nl 20130827',
2 => 'bas#dikkenberg.net 20140825',
3 => 'bas#hobby.nl 20120825',
4 => 'ripe#hobby.nl 20140826'
);
$count_data = count($data);
for($i=0;$i<$count_data;$i++)
{
$new_data[trim(strstr($data[$i], ' '))]=$data[$i];
}
echo "<pre>"; print_r($new_data);
?>
this will return you
Array
(
[20140827] => ripe#hobby.nl 20140827
[20130827] => bas#hobby.nl 20130827
[20140825] => bas#dikkenberg.net 20140825
[20120825] => bas#hobby.nl 20120825
[20140826] => ripe#hobby.nl 20140826
)
Now you can sort according to need by Key
You could loop through the array, explode the string on a space, ' ', then set part one $explodedString[1] as the key in a new array, then use ksort on the new array.
Untested code.
$oldArr;
$newArr = array();
foreach($oldArr as $oldStr){
$tmpStr = explode(' ', $oldStr);
$newArr[$tmpStr[1]] = $tmp[0]; //You could use $oldStr if you still needed the numbers.
}
ksort($newArr);

Categories