I've a muti dimensional array. I want to concatenate 2 strings separately for 2 array values and the 2 strings should not be concatenated for a single value. I want CM and PM concatenated 2 times any where in the array. I've tried looping the array and generating array_rand but i generates only once. Any help is much appreciated. Below is one example of what am achieving.
Thing am trying to achieve
Concatenate "PM" and "CM" string in one set of array and same value can't be CM and PM
Every array should have PM and CM concatenated
1 "Name" value should have minimum 1 CM and PM and Maximum 2 CM and PM
For example: I've the below multi dimensional array.
Array
(
[0] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[1] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[2] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[3] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[4] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
)
After concatenating
Array
(
[0] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C["PM"]
[3] => Name-4["CM"]
[4] => Name-5
)
[1] => Array
(
[0] => Name-A
[1] => Name-B["PM"]
[2] => Name-C
[3] => Name-4["CM"]
[4] => Name-5
)
[2] => Array
(
[0] => Name-A["PM"]
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5["CM"]
)
[3] => Array
(
[0] => Name-A["PM"]
[1] => Name-B["CM"]
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[4] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C["CM"]
[3] => Name-4
[4] => Name-5["PM"]
)
)
Sorry I didn't understand at first.
Given $your_array:
// Generate an array where the names are the key, and assign a zero value to PM (0) and CM (1) in a sub array
$ar = array_fill_keys($your_array[0], array (0 => 0, 1 => 0));
//$array the sub_value, $add the case PM ou CM, $exclusion is the key used the first time
function rand_in_array($array, $add, $ar, $exclusion)
{
// Select a random key
$arr_key = array_rand($array, 1);
if($ar[$array[$arr_key]][$add] < 2 && ($arr_key != $exclusion))
{
return $arr_key;
}
return rand_in_array($array, $add, $ar, $exclusion);
}
for($i=0; $i<count($your_array);$i++)
{
$arr_key_pm = rand_in_array($your_array[$i], 0, $ar, 99);
$ar[$your_array[$i][$arr_key_pm]][0]++;
$arr_key_cm = rand_in_array($your_array[$i], 1, $ar, $arr_key_pm);
$ar[$your_array[$i][$arr_key_cm]][1]++;
$your_array[$i][$arr_key_pm] .= "PM";
$your_array[$i][$arr_key_cm] .= "CM";
}
It is ugly but it works :)
Somewhere should existe someone able to make more aesthetic..
for($i=0; $i<count($your_array);$i++)
{
$arr_keys = array_rand($your_array[$i], 2);
$your_array[$i][$arr_keys[0]] .= "PM";
$your_array[$i][$arr_keys[1]] .= "CM";
}
Should do the work.
I assume your inner array index is starting from zero. So generate the random index between 0 to your ( inner_array_size - 1). Then assign the value in the array's reference variable withing the loop.
foreach ($arr as &$value) {
$randomIndex = array_rand(range(0, (count($value) -1) ), 2);
$value[$randomIndex[0]] .= ' ["CM"]';
$value[$randomIndex[1]] .= ' ["PM"]';
}
Related
I have two arrays, $full_list and $only_titles with matching value based on first key.
$full_list:
Array
(
[0] => Array
(
[0] => samsung-a40
[1] => Samsung A40 Phone
[2] =>
[3] => 21
[4] => 334234
[5] => 0
)
[1] => Array
(
[0] => samsung-a72
[1] => Galaxy A72 Phone
[2] =>
[3] => 230
[4] => 239049
[5] => 0
)
[2] => Array
(
[0] => lg-k61
[1] => LG K61 Phone
[2] =>
[3] => 22
[4] => 249582
[5] => 0
)
etc...
$only_titles:
Array
(
[0] => Array
(
[0] => samsung-a40
[1] => Black Phone Case For Samsung A40
)
[1] => Array
(
[0] => lg-k61
[1] => Red Case LG K61 Phone
)
[2] => Array
(
[0] => samsung-a72
[1] => Folding Phone Case for Galaxy A72 Phone
)
etc...
I want to take value from second key from $only_title array (its basicaly long product title) and replace it in the $full_list array:
$final_result:
Array
(
[0] => Array
(
[0] => samsung-a40
[1] => Black Phone Case For Samsung A40 // title from $only_titles
[2] =>
[3] => 21
[4] => 334234
[5] => 0
)
[1] => Array
(
[0] => samsung-a72
[1] => Folding Phone Case for Galaxy A72 Phone // title from $only_titles
[2] =>
[3] => 230
[4] => 239049
[5] => 0
)
[2] => Array
(
[0] => lg-k61
[1] => Red Case LG K61 Phone // title from $only_titles
[2] =>
[3] => 22
[4] => 249582
[5] => 0
)
etc...
I have tried array_replace_recursive(), but the problem with this is that it expects that the order of subarrays are the same. But as you can see in both arrays the second subarrays dont match. With array_replace_recursive() i get the second subarray wrong:
[1] => Array
(
[0] => samsung-a72
[1] => Red Case LG K61 Phone // this is wrong
[2] =>
[3] => 230
[4] => 239049
[5] => 0
)
How can I check if values from first key match?
You can utilize array_map and array_search for your task.
$items = array_map(function($item) use ($only_titles) {
$index = array_search($item[0], array_column($only_titles, 0));
if($index === false) return;
$item[1] = $only_titles[$index][1];
return $item;
}, $full_list);
array_map() takes $full_list and iterate each item as $item,
then for each item, we look for the matching title with array_search()
It will return an index from $only_titles.
We can use $index to reference and assign the long title to item.
The result are in $items
This script will help you to solve your problem
<?php
$full_array = [
[
'samsung-a40',
'Samsung A40 Phone',
null,
21,
334234,
0,
],
[
'samsung-a72',
'Galaxy A72 Phone',
null,
230,
239049,
0,
],
];
$only_titles = [
[
'samsung-a40',
'Black Phone Case For Samsung A40',
],
[
'samsung-a72',
'Red Case LG K61 Phone ',
],
];
$formattedOnlyTitles = [];
foreach ($only_titles as $value) {
$formattedOnlyTitles[$value[0]] = $value[1];
}
$fullArrayWithNewTitle = [];
foreach ($full_array as $value) {
if (isset($formattedOnlyTitles[$value[0]])) {
$value[1] = $formattedOnlyTitles[$value[0]];
}
$fullArrayWithNewTitle[] = $value;
}
print_r($fullArrayWithNewTitle);
output
Array
(
[0] => Array
(
[0] => samsung-a40
[1] => Samsung A40 Phone
[2] =>
[3] => 21
[4] => 334234
[5] => 0
)
[1] => Array
(
[0] => samsung-a72
[1] => Galaxy A72 Phone
[2] =>
[3] => 230
[4] => 239049
[5] => 0
)
)
First I change the format of the title_only var to make is easy to work with it in the next foreach
$formattedOnlyTitles = [];
foreach ($only_titles as $value) {
$formattedOnlyTitles[$value[0]] = $value[1];
}
In the next foreach I just check the title with my new formatted title_only array
if (isset($formattedOnlyTitles[$value[0]])) {
$value[1] = $formattedOnlyTitles[$value[0]];
}
And then change the title if I need
bit of a question here. Ive got an array that contains data which has been parsed from a website using all our favourite php functions such as array_map.
The array is current 3 sub arrays deep.
Here is the code I am using:
for ($tcid = 1; $tcid <= count($categories); $tcid++) {
$catHeader[$tcid] = $categories[$tcid][0];
$event[$i]['tickets'] = $categories;
unset($categories[$tcid][0]);
$categories[$tcid] = array_map('trim', $categories[$tcid]);
$categories[$tcid] = array_values($categories[$tcid]);
$ab = 0;
for ($b = 0; $b <= count($categories[$tcid]); $b++) {
if ($categories[$tcid][$b] == "" || !$categories[$tcid][$b] || $categories[$tcid][$b] == null) {
unset($categories[$tcid][$b]);
}
}
}
and the array looks something like....
[1] => Array (
[data] => Array ( ...
)
[tickets] => Array (
[1] => Array (
[0] => xxx
[1] => etc
[3] => etc2
)
[2] => (
[0] => Std1
[1] => 10 / 10
[2] => £20.00
[3] => £200.00
[4] => Std2
[5] => 100 / 100
[6] => £13.00
[7] => £1,300.00
[8] => Std3
[9] => 10 / 320
[10] => £15.00
[11] => £150.00
)
)
)
My question to you today, is how on earth do I split the array every 4 \n's or array keys as they're known and explode each 4 into a further sub array?
So that Std1, Std2, Std3 will be their own sub array with its associated data of the 2nd key of tickets, but also doing this for every sub array of tickets that has more than 1 set of data (a set of data being 4 array keys).
I've tried all sorts but can't get it to work.
See below of how I want it to look.
[1] => Array (
[data] => Array ( ...
)
[tickets] => Array (
[1] => Array (
[0] => xxx
[1] => etc
[3] => etc2
)
[2] => (
[0] => Array (
[0] => Std1
[1] => 10 / 10
[2] => £20.00
[3] => £200.00
)
[1] => Array (
[0] => Std2
[1] => 100 / 100
[2] => £13.00
[3] => £1,300.00
)
[2] => Array (
[0] => Std3
[1] => 10 / 320
[2] => £15.00
[3] => £150.00
)
)
)
)
Thanks
As noted in the comments, you'd be best off handling your array by-reference to modify it's original contents somewhere within your loops
Provided the array groupings you want to chunk are in groups of 4, you could array_chunk() it:
$array['tickets'][2] = array_chunk($array['tickets'][2], 4);
I hope you could help me on how should I make this output be done.
CSV file
Department,Name,Employee No.,Date Time
LMS,"Bach, Jerome",102,6/30/2014 12:23
MTS,"Lorvia, Christine",103,6/16/2014 9:31
SSS,Jannah Curtis,104,6/16/2014 8:45
SSS,Jannah Curtis,104,6/28/2014 14:29
ITM,Sassy Mica,105,6/17/2014 9:12
ITM,Sassy Mica,105,6/17/2014 20:43
ITM,Sassy Mica,105,6/18/2014 9:12
I already grouped the department and this is the output
[MTS] => Array
(
[103] => Array
(
[0] => MTS
[1] => Lorvia Christine
[2] => 103
[3] => 6/16/2014 9:31
)
)
[SSS] => Array
(
[104] => Array
(
[0] => SSS
[1] => Jannah Curtis
[2] => 104
[3] => 6/28/2014 14:29
)
)
[ITM] => Array
(
[105] => Array
(
[0] => ITM
[1] => Sassy Mica
[2] => 105
[3] => 6/18/2014 9:12
)
)
but I want an output that will result all her date/time record under the element [3].
Ex.
[ITM] => Array
(
[105] => Array
(
[0] => ITM
[1] => Sassy Mica
[2] => 105
[3] => 6/17/2014 9:12
=> 6/17/2014 20:43
=> 6/18/2014 9:12
)
)
While the time record is sorted.
You don't have a choice. You need to process them accordingly. The array format you desire is invalid, since they cannot share the same key, just create another dimension for the time. Example:
$data = array();
$handle = fopen('sample.csv', 'r');
while(!feof($handle)) {
$row = fgetcsv($handle, '4096');
if(!isset($data[$row[0]][$row[2]])) {
// simple assignment
$data[$row[0]][$row[2]] = array($row[0], $row[1], $row[2], array($row[3],));
} else {
// process
$data[$row[0]][$row[2]][3][] = $row[3]; // push it inside instead of assigning a new one
$temp = $data[$row[0]][$row[2]][3]; // temporary storage
$temp = array_map(function($var){
return strtotime($var); // convert to unix time
}, $temp);
sort($temp); // sort ascending
$data[$row[0]][$row[2]][3] = array_map(function($var){
return date('m/d/Y H:i', $var); // return to old format with sorted values
}, $temp);
}
}
array_shift($data); // remove the first (the header)
echo '<pre>';
print_r($data);
Should yield something like:
Array
(
[LMS] => Array
(
[102] => Array
(
[0] => LMS
[1] => Bach, Jerome
[2] => 102
[3] => Array
(
[0] => 6/30/2014 12:23
)
)
)
[MTS] => Array
(
[103] => Array
(
[0] => MTS
[1] => Lorvia, Christine
[2] => 103
[3] => Array
(
[0] => 6/16/2014 9:31
)
)
)
[SSS] => Array
(
[104] => Array
(
[0] => SSS
[1] => Jannah Curtis
[2] => 104
[3] => Array
(
[0] => 06/16/2014 08:45
[1] => 06/28/2014 14:29
)
)
)
[ITM] => Array
(
[105] => Array
(
[0] => ITM
[1] => Sassy Mica
[2] => 105
[3] => Array
(
[0] => 06/17/2014 09:12
[1] => 06/17/2014 20:43
[2] => 06/18/2014 09:12
)
)
)
)
I stuck on this and really don't know how to solve it.
I have two multi-dimensional arrays and need to match every "entry_id" from second array with first one. Then need to check if every "file_no" from second array is in database (first array) and "status" are matched with 1st array . If "status" is different, update second array with string (e.g. updated value) like this:
...
[status] => Array
(
[0] => abc
[1] => defghijk - "updated value"
)
So I have first array from database:
Array
(
[0] => Array
(
[entry_id] => 1
[file_no] => KSBR 40 INS 3674 / 2014
[status] => abc
)
[1] => Array
(
[entry_id] => 9
[file_no] => KSUL 77 INS 18898 / 2013
[status] => abc
)
[2] => Array
(
[entry_id] => 9
[file_no] => KSUL 77 INS 21218 / 2013
[status] => defg
)
)
And second array generated from script:
Array
(
[0] => Array
(
[entry_id] => 1
[id] => 500910/098
[fullname] => Milan Vrtal
[type] => person
[file_no] => Array
(
[0] => KSBR 26 INS 37146 / 2013
[1] => KSBR 40 INS 3674 / 2014
)
[status] => Array
(
[0] => status1
[1] => status2
)
)
[1] => Array
(
[entry_id] => 2
[id] => 46900217
[fullname] => ENTEC a.s.
[type] => company
[file_no] => Array
(
[0] => KSBR 28 INS 1232 / 2013
)
[status] => Array
(
[0] => qwer
)
)
[2] => Array
(
[entry_id] => 9
[fullname] => Blanka Kořínková
[type] => person
[file_no] => Array
(
[0] => KSUL 77 INS 18898 / 2013
[1] => KSUL 77 INS 21218 / 2013
)
[status] => Array
(
[0] => abc
[1] => defghijk
)
)
)
Thanks for every comment and sorry for english :)
This is by creating a temporary array to search in. This will use quite some memory when the arrays are big, but will result in faster execution time...
$tmparr = array();
foreach($arr1 as $arr1_val)
{
//put an new element in $temparr with key 'entry_id' and an array as value
if (!isset($tmparr[$arr1_val['entry_id']]))
$tmparr[$arr1_val['entry_id']] = array();
//add the status to the array
$tmparr[$arr1_val['entry_id']][] = $arr1_val['status'];
}
/*
$tmparr = Array
(
[1] => Array
(
[0] => abc
)
[9] => Array
(
[0] => abc
[1] => defg
)
)
*/
//arr2_val by reference so that we can change it
foreach($arr2 as &$arr2_val)
{
//get the current entry_id
$entry_id = $arr2_val['entry_id'];
//see if this entry_id was in the first array, and if so...
if (isset($tmparr[$entry_id]))
{
//change the status to both the original status and the status of the first array
$arr2_val['status'] = array_merge($arr2_val['status'],$tmparr[$entry_id]);
}
}
print_r($arr2);
Output:
Array
(
[0] => Array
(
[entry_id] => 1
[id] => 500910/098
[fullname] => Milan Vrtal
[type] => person
[file_no] => Array
(
[0] => KSBR 26 INS 37146 / 2013
[1] => KSBR 40 INS 3674 / 2014
)
[status] => Array
(
[0] => status1
[1] => status2
[2] => abc
)
)
[1] => Array
(
[entry_id] => 2
[id] => 46900217
[fullname] => ENTEC a.s.
[type] => company
[file_no] => Array
(
[0] => KSBR 28 INS 1232 / 2013
)
[status] => Array
(
[0] => qwer
)
)
[2] => Array
(
[entry_id] => 9
[fullname] => Blanka Kořínková
[type] => person
[file_no] => Array
(
[0] => KSUL 77 INS 18898 / 2013
[1] => KSUL 77 INS 21218 / 2013
)
[status] => Array
(
[0] => abc
[1] => defghijk
[2] => abc
[3] => defg
)
)
)
edit: This is possible too, whitout the temp array, but with a loop in a loop. This will be slower than the first one, but will consume less memory:
//arr2_val by reference so that we can change it
foreach($arr2 as &$arr2_val)
{
//get the current entry_id
$entry_id = $arr2_val['entry_id'];
//search for the correct row in the first array
foreach($arr1 as $arr1_val)
{
if ($arr1_val['entry_id'] == $arr2_val['entry_id'])
{
$arr2_val['status'][] = $arr1_val['status'];
//a continue should be added here to make it faster...
}
}
}
print_r($arr2);
This should work
foreach($array1 as $i)
{
foreach($array2 as $key=>$j)
{
if($j['entry_id'] == $i['entry_id'])
{
if($array2[$key]['status'] != $i['status'])
{
$j['status'] = array(
$i['status'],
$j['status'] // the new status
);
}
continue;
}
}
}
I found a solution for you :
$a1 = [['entry_id' => 1, 'file_no' => 'KSBR', 'status' => 'abc'], ['entry_id' => 2, 'file_no' => 'KSUL', 'status' => 'defg']];
$a2 = [['entry_id' => 1, 'file_no' => 'KSBR', 'status' => 'abc', 'type' => 'person'], ['entry_id' => 2, 'file_no' => 'KSUL', 'status' => 'defg']];
print_r(new_array_merge_recursive($a1, $a2));
function new_array_merge_recursive(array $array1, array $array2=array())
{
$arrays = func_get_args();
$merge = array_shift($arrays);
foreach ($arrays as $array)
{
foreach ($array as $key => $val)
{
if (is_array($val) && array_key_exists($key, $merge))
{
$val = new_array_merge_recursive((array) $merge[$key], $val);
}
$merge[$key] = $val;
}
}
return $merge;
}
i have created a function in php to convert an string like:
[20110911, 20110913, [20110915, 20110918], 20110920, 20110922, 20110924, [20110926, 20110927], 20110929]
to php array like:
Array
(
[0] => 20110911
[1] => 20110913
[2] => Array
(
[0] => 20110915
[1] => 20110918
)
[3] => 20110920
[4] => 20110922
[5] => 20110924
[6] => Array
(
[0] => 20110926
[1] => 20110927
)
[7] => 20110929
[8] => Array
(
[0] => 20111001
[1] => 20111002
)
[9] => 20111004
[10] => Array
(
[0] => 20111006
[1] => 20111007
)
)
The function is:
function dates2Array($d){
if($d!==''){
$d=substr($d, 1, strlen($d)-2);
$d=explode(', ', $d);
$dates=array();
if(!empty($d)){
$j=1;
foreach($d as $k=>$v){
if(substr($v, 0, 1)==='[') $dates[]=array(substr($v, 1, strlen($v)));
elseif(substr($v, strlen($v)-1, strlen($v))===']'){
$dates[$k-$j][1]=substr($v, 0, strlen($v)-1);
$j++;
}
else $dates[]=$v;
}
}
}
return $d!==''?$dates:'';
}
I am not fully happy with my function.
I think it can be more optimized and compressed for speed..
Can it be?
Use JSON (json_decode() and json_encode()) instead
http://sandbox.phpcode.eu/g/b3814/2
result:
Array
(
[0] => 20110911
[1] => 20110913
[2] => Array
(
[0] => 20110915
[1] => 20110918
)
[3] => 20110920
[4] => 20110922
[5] => 20110924
[6] => Array
(
[0] => 20110926
[1] => 20110927
)
[7] => 20110929
)
You can pass your string in {...} and pass it to json_decode(str, true) to get back an array.
>> json_decode("[20110911, 20110913, [20110915, 20110918], 20110920, 20110922, 2
0110924, [20110926, 20110927], 20110929]")
array (
0 => 20110911,
1 => 20110913,
2 =>
array (
0 => 20110915,
1 => 20110918,
),
3 => 20110920,
4 => 20110922,
5 => 20110924,
6 =>
array (
0 => 20110926,
1 => 20110927,
),
7 => 20110929,
)