I have a multidimensional array like so:
array(4) {
[0] => array(2) {
[0] => string(15)
"One"
[1] => string(5)
"11:31"
}
[1] => array(2) {
[0] => string(4)
"Two"
[1] => string(5)
"11:31"
}
[2] => array(2) {
[0] => string(15)
"Three"
[1] => string(5)
"11:31"
}
[3] => array(2) {
[0] => string(4)
"One"
[1] => string(5)
"11:31"
}
}
I am trying to get the ones with the first value removed but added up together. So it would end up like so:
array(3) {
[0] => array(2) {
[0] => string(15)
"One"
[1] => string(5)
"22:62"
}
[1] => array(2) {
[0] => string(4)
"Two"
[1] => string(5)
"11:31"
}
[2] => array(2) {
[0] => string(15)
"Three"
[1] => string(5)
"11:31"
}
}
Note the last 'One' has been removed and the second value in the array has been added up there from two 11:31's to 22:62. I hope that makes sense.
Is there something or a specific function I should look at to push me in the right direction? Any help much appreciated.
This is not just a straight up removing duplicates from what I can tell, as none are ever exactly the same although the second values are in this example, they won't be in live data.
You could make a loop and group elements into a new array using key [0]. It the key doesn't exists in the new array, simply add the new array. Otherwise, you could parse the existing value to add the new value:
$array = [
["One", "11:31"],
["Two", "11:31"],
["Three", "11:31"],
["One", "11:31"],
];
$out = [];
foreach ($array as $item) {
// if $item[0] is not an existing key,
if (!isset($out[$item[0]])) {
// add $item as-is
$out[$item[0]] = $item;
} else {
// parse current time
list($h1, $m1) = explode(':', $item[1]);
$m1 += $h1 * 60;
// parse existing time
list($h2, $m2) = explode(':', $out[$item[0]][1]);
$m1 += $m2 + $h2 * 60;
// compute new time
$h = floor($m1 / 60);
$out[$item[0]][1] = sprintf("%02d:%02d", $h, $m1-$h*60);
}
}
// array_values removes 'named' keys.
print_r(array_values($out));
Output (condensed):
Array
(
[0] => Array ([0] => One [1] => 23:02)
[1] => Array ([0] => Two [1] => 11:31)
[2] => Array ([0] => Three [1] => 11:31)
)
Related
I have not even started the codeing process, because i cant figure out the logic.
I have 2 arrays
$urls = array(0 => url1,
1 => url2,
2 => url3,
3 => url4);
$domains = array(0 => domain_a,
1 => domain_b,
2 => domain_c,
3 => domain_d);
i need and output like
[0] => array ( [domain] => domain_a
[urls] => array (
[0] => url2,
[1] => url4 ))
[1] => array ( [domain] => domain_b
[urls] => array (
[0] => url1,
[1] => url3 ))
[2] => array ( [domain] => domain_c
[urls] => array (
[0] => url1,
[1] => url4 ))
[3] => array ( [domain] => domain_d
[urls] => array (
[0] => url2,
[1] => url3 ))
Until all domains has bin packed with 2 urls. The packing of the urls must be random, but the use of each url must be the same, or close to the same.
If you ever can't do something, the best thing is to break it down into chunks.
The answer to your question is likely to create a copy of the array of urls, and loop through the domains adding two of these urls each time — at random. When you do so, remove the item from the array. If the copy of urls is empty, create a fresh copy.
// The output
$output = [];
// The selection of arrays. We can populate this later...
$selection = [];
// Loop through every domain...
foreach($domains as $domain){
// Create the template that you want in the output. So far this is nearly the whole way there, we just need to add the random urls
$newItem = [
"domain" => $domain,
"urls" => []
];
// You want 2 urls per domain, so we'll do a for loop twice. ($i < 2)
for($i = 0; $i < 2; $i++){
// If the $selection list is empty (it will be at the start of the function, and also in your example on domain_c make a simple copy of the urls)
if(count($selection) <= 0){
$selection = $urls;
}
// Now find a random key for an item in the array
$randomKey = array_rand($selection);
// Push the item into the array of urls
$newItem["urls"][] = $selection[$randomKey];
// remove it from the array of items to pick from (so it won't come up again until you create a new copy, after all the others are used)
unset($selection[$randomKey]);
}
// Add this to the output:
$output[] = $newItem;
}
Using shuffle() and a simple foreach should be enough to do the job. For an arbitrary number of domains to be distributed randomly onto another number of urls use the following script:
$url=array('url1','url2','url3','url4');
$dom=array('dom_a','dom_b','dom_c');
$urls=$url; // copy the array
shuffle($urls); // shuffle the domains
$ul=count($urls); // length of $url
$dl=count($dom); // length of $dom
foreach ($urls as $k => $u)
$res[$k]=["domain"=>$dom[$k%$dl], "urls"=>[$u,$urls[($k+1)%$ul]]];
print_r($res);
See DEMO here: https://rextester.com/PFS53297
This code provides for a different number of domains and URLs in the input:
$urls = array(
0 => 'url1',
1 => 'url2',
2 => 'url3',
3 => 'url4'
);
$domains = array(
0 => 'domain_a',
1 => 'domain_b',
2 => 'domain_c',
3 => 'domain_d'
);
$result = [];
foreach ($domains as $domain) {
$urlsBucket = [];
while (count($urlsBucket) < 2) { // We need only 2 URLs
$randomUrl = $urls[array_rand($urls)]; // Get random URL
if (in_array($randomUrl, $urlsBucket)) { // To avoid duplication in the URL list
continue;
}
$urlsBucket[] = $randomUrl;
}
$result[] = [
'domain' => $domain,
'urls' => $urlsBucket
];
}
var_dump($result);
Output:
array(4) {
[0]=>
array(2) {
["domain"]=>
string(8) "domain_a"
["urls"]=>
array(2) {
[0]=>
string(4) "url2"
[1]=>
string(4) "url1"
}
}
[1]=>
array(2) {
["domain"]=>
string(8) "domain_b"
["urls"]=>
array(2) {
[0]=>
string(4) "url2"
[1]=>
string(4) "url4"
}
}
[2]=>
array(2) {
["domain"]=>
string(8) "domain_c"
["urls"]=>
array(2) {
[0]=>
string(4) "url3"
[1]=>
string(4) "url1"
}
}
[3]=>
array(2) {
["domain"]=>
string(8) "domain_d"
["urls"]=>
array(2) {
[0]=>
string(4) "url1"
[1]=>
string(4) "url2"
}
}
}
DEMO: https://paiza.io/projects/c9rXHcprCgsWnUlJ9UNNsg?language=php
I have 2 PHP arrays that I need to combine values together.
First Array
array(2) {
[0]=>
array(1) {
["id"]=>
string(1) "1"
}
[1]=>
array(1) {
["id"]=>
string(2) "40"
}
}
Second Array
array(2) {
[0]=>
string(4) "1008"
[1]=>
string(1) "4"
}
Output desired
array(2) {
[0]=>
array(1) {
["id"]=>
string(1) "1",
["count"]=>
string(1) "1008"
}
[1]=>
array(1) {
["id"]=>
string(2) "40",
["count"]=>
string(1) "4"
}
}
As you can see I need to add a new key name (count) to my second array and combine values to my first array.
What can I do to output this array combined?
Try something like the following. The idea is to iterate on the first array and for each array index add a new key "count" that holds the value contained on the same index of the second array.
$array1 = [];
$array2 = [];
for ($i = 0; $i < count($array1); $i++) {
$array1[$i]['count'] = $array2[$i];
}
you can do it like this
$arr1=[["id"=>1],["id"=>40]];
$arr2=[1008,4];
for($i=0;$i<count($arr2);$i++){
$arr1[$i]["count"] = $arr2[$i];
}
Live demo : https://eval.in/904266
output is
Array
(
[0] => Array
(
[id] => 1
[count] => 1008
)
[1] => Array
(
[id] => 40
[count] => 4
)
)
Another functional approach (this won't mutate/change the initial arrays):
$arr1 = [['id'=> "1"], ['id'=> "40"]];
$arr2 = ["1008", "4"];
$result = array_map(function($a){
return array_combine(['id', 'count'], $a);
}, array_map(null, array_column($arr1, 'id'), $arr2));
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => 1
[count] => 1008
)
[1] => Array
(
[id] => 40
[count] => 4
)
)
Or another approach with recursion:
$arr1=[["id"=>1],["id"=>40]];
$arr2=[1008,4];
foreach ($arr1 as $key=>$value) {
$result[] = array_merge_recursive($arr1[$key], array ("count" => $arr2[$key]));
}
print_r($result);
And output:
Array
(
[0] => Array
(
[id] => 1
[count] => 1008
)
[1] => Array
(
[id] => 40
[count] => 4
)
)
My code contains an array that has 7 elements and each element has a total number of different characters. I want, when the number of characters meets the criteria (<= 6) then create a new array.
The output is expected in the form of a two dimension array,
// My Variables, $value & $count
$value=array('as','fix','fine','is','port','none','hi','of');
for ($i=0; $i <count($value) ; $i++) {
$count[]=strlen($value[$i]);
}
Then have output like a,
// $value,
Array
(
[0] => as
[1] => fix
[2] => fine
[3] => is
[4] => port
[5] => none
[6] => hi
[7] => of
)
// Count the length $value and store in Variable $count,
Array
(
[0] => 2
[1] => 3
[2] => 4
[3] => 2
[4] => 4
[5] => 4
[6] => 2
[7] => 2
)
and then I hope my code can produce output like this:
(Explode element where length <= 6)
// If length value in the variable $count,
Array
(
[0] => 2
[1] => 3
Total Length(5)
[2] => 4
[3] => 2
Total Length(6)
[4] => 4
Total Length(4)
[5] => 4
Total Length(4)
[6] => 2
[7] => 2
Total Length(4)
)
This is my question point:
// $Values RESULT
Array
(
[0] => Array
(
[0] => as
[1] => fix
)
[1] => Array
(
[0] => fine
[1] => is
)
[1] => Array
(
[0] => port
)
[1] => Array
(
[0] => none
)
[1] => Array
(
[0] => hi
[1] => of
)
)
Your examples were a bit hard to follow but here's what I've got:
<?php
$value=array('as','fix','fine','is','port','none','hi','of');
$final = [];
$accumulator = 0;
$final[0] = [];
$x = 0;
for ($i=0; $i <count($value) ; $i++) {
var_dump($accumulator);
if($accumulator + strlen($value[$i]) > 6) {
echo "adding ".$value[$i] ." to new\n\n";
$x++;
$final[$x] = [];
array_push($final[$x], $value[$i]);
$accumulator = strlen($value[$i]);
}else{
echo "adding ".$value[$i] . " to existing\n\n";
array_push($final[$x], $value[$i]);
$accumulator += strlen($value[$i]);
}
}
var_dump($final);
Yields
int(0)
adding as to existing
int(2)
adding fix to existing
int(5)
adding fine to new
int(4)
adding is to existing
int(6)
adding port to new
int(4)
adding none to new
int(4)
adding hi to existing
int(6)
adding of to new
array(5) {
[0]=>
array(2) {
[0]=>
string(2) "as"
[1]=>
string(3) "fix"
}
[1]=>
array(2) {
[0]=>
string(4) "fine"
[1]=>
string(2) "is"
}
[2]=>
array(1) {
[0]=>
string(4) "port"
}
[3]=>
array(2) {
[0]=>
string(4) "none"
[1]=>
string(2) "hi"
}
[4]=>
array(1) {
[0]=>
string(2) "of"
}
}
http://sandbox.onlinephpfunctions.com/code/20a63b83ad5524c5cd77e111bc15e197bf8bfba2
I have this ARRAY sent from a FORM
Array
(
[0] => one
two
three
[1] => hello
how
are
)
Since the values are sent via textarea from a form, it has line breakers, so I want to make change every into a array field like so:
Array
(
[0] => Array
(
[0] => one
[1] => two
[2] => three
)
[1] => Array
(
[0] => hello
[1] => how
[2] => are
)
)
This is what I have so far:
foreach ($array as &$valor) {
foreach(preg_split("/((\r?\n)|(\r\n?))/", $valor) as $line){
$arraynew[] = $line;
}
}
But I get this result
Array
(
[0] => one
[1] => two
[2] => three
[3] => hello
[4] => how
[5] => are
)
What am I doing wrong? :(
For each key in the POST array, pop a value onto the final array, with it's values containing an array whoses values represent each line in value of the POST array.
<?php
$data = array(
0 => "one\ntwo\nthree",
1 => "hello\nhow\nare"
);
$final = array();
for($i = 0; $i < count($data); $i++) {
$row = preg_split('/\n/', $data[$i]);
if(is_array($row)) {
for($j = 0; $j < count($row); $j++) {
$final[$i][] = $row[$j];
}
}
}
var_dump($final);
array(2) {
[0] =>
array(3) {
[0] =>
string(3) "one"
[1] =>
string(3) "two"
[2] =>
string(5) "three"
}
[1] =>
array(3) {
[0] =>
string(5) "hello"
[1] =>
string(3) "how"
[2] =>
string(3) "are"
}
}
DEMO
Well, you're really working too hard.
array_map(function($e) { return explode("\n", $e); }, $orig_array);
is all you need. You could use preg_split if you really want, but explode is enough.
You can simply do this
$array=array("one\ntwo\nthree","hello\nhow\nare");
$arraynew=array();
foreach ($array as &$valor) {
$arraynewtemp=array();
foreach(preg_split("/((\r?\n)|(\r\n?))/", $valor) as $line){
$arraynewtemp[] = $line;
}
array_push($arraynew,$arraynewtemp);
}
var_dump($arraynew);
Will output
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "one"
[1]=>
string(3) "two"
[2]=>
string(5) "three"
}
[1]=>
array(3) {
[0]=>
string(5) "hello"
[1]=>
string(3) "how"
[2]=>
string(3) "are"
}
}
This should works
I want to remove duplicate values from multi-dim array, I tried all the possible solutions which is already described but for me, is not working, can anyone please correct it?
Here's my Array:
Array (
[0] => Array (
[0] => element_10
[1] => block_1
[2] => element_4
[3] => element_1
[4] => element_3
)
[1] => Array (
[0] => block_1
[1] => block_2
[2] => element_8
[3] => element_10
[4] => element_12
[5] => element_14
[6] => element_4
[7] => element_2
[8] => element_3
[9] => element_9
[10] => element_13
[11] => element_7
)
)
Where I want the array in this format:
Array (
[0] => Array (
[0] => element_10
[1] => block_1
[2] => element_4
[3] => element_1
[4] => element_3
)
[1] => Array (
[1] => block_2
[2] => element_8
[4] => element_12
[5] => element_14
[7] => element_2
[9] => element_9
[10] => element_13
[11] => element_7
)
)
Ican setup the key indexes later.
I tried:
function multi_unique($array) {
foreach ($array as $k=>$na)
$new[$k] = serialize($na);
$uniq = array_unique($new);
foreach($uniq as $k=>$ser)
$new1[$k] = unserialize($ser);
return ($new1);
}
No Luck, then I tried:
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
Still same array returning.
I tried this method too:
function super_unique($array)
{
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
foreach ($result as $key => $value)
{
if ( is_array($value) )
{
$result[$key] = self::super_unique($value);
}
}
return $result;
}
Please help me, I know it's pretty simple I don't know where I'm losing?
Thanks,
You need to iterate over your list of input arrays. For each value in that array, you need to see if you've previously encountered it, so you'll have to keep a super-set of all values across all arrays, which you gradually append to. If a value already exists in the super-set array, you can remove it, otherwise you can append it.
function multi_unique($arrays) {
$all_values = array();
foreach ($arrays as &$array) {
foreach ($array as $index => $value) {
if (in_array($value, $all_values)) {
// We've seen this value previously
unset($array[$index]);
} else {
// First time we've seen this value, let it pass but record it
$all_values[] = $value;
}
}
}
return $arrays;
}
$values = array (
array ( 'element_10', 'block_1', 'element_4', 'element_1', 'element_3',) ,
array ( 'block_1', 'block_2', 'element_8', 'element_10', 'element_12', 'element_14', 'element_4', 'element_2', 'element_3', 'element_9', 'element_13', 'element_7',)
);
var_dump(multi_unique($values));
Output:
array(2) {
[0]=>
array(5) {
[0]=>
string(10) "element_10"
[1]=>
string(7) "block_1"
[2]=>
string(9) "element_4"
[3]=>
string(9) "element_1"
[4]=>
string(9) "element_3"
}
[1]=>
array(8) {
[1]=>
string(7) "block_2"
[2]=>
string(9) "element_8"
[4]=>
string(10) "element_12"
[5]=>
string(10) "element_14"
[7]=>
string(9) "element_2"
[9]=>
string(9) "element_9"
[10]=>
string(10) "element_13"
[11]=>
string(9) "element_7"
}
}
If you just want to remove duplicates from the second entry of your array, use array_diff():
$array[1] = array_diff($array[1], $array[0]);
Iterate if you want to apply it to an arbitrary length.
Why are you using the serialize function.
Use array_diff instead.
A simple would be.
$orginal = array(array(values), array(values), ...);
$copy = $original;
foreach($original as $k => $subArray) {
$tmpCopy = $copy;
unset($tmpCopy[$k]);
unshift($tmpCopy, $subArray);
$tmpCopy = array_values($tmpCopy);
$original[$k] = call_user_func_array('array_diff', $tmpCopy);
}
This works for a two dimensions array.
Hope it helps.