i have 1 array like below :
0 => array:4 [
"id" => "1"
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
]
1 => array:4 [
"id" => "2"
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
]
now what i want to do ?? as you can see the date and from_time and to_time have the same value . i want to merge them to 1 item like below :
0 => array:4[
"date" => "2021-08-03"
"from_time" => "09"
"to_time" => "14"
"id" => ["1" , "2"]
].
so i can have the same day ids in 1 index of array and if for example the same date and time got 4 ids i get the id key with 4ids . i used array_merge_recursive but it didnt help me with the same keys of an array
this is how i am building the array :
foreach ($arrays as $key => $array) {
$options[$key]['id'] = last(str_split($array['id']));
$options[$key]['date'] = substr($array['id'],0,-2);
$options[$key]['from_time'] = Carbon::createFromTimestamp($array['pickup']['from'])->format('H');
$options[$key]['to_time'] = Carbon::createFromTimestamp($array['pickup']['to'])->format('H');
}
. thanks in advance for help
<?php
//define items
$items = [
[
"id" => "1",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14",
],[
"id" => "2",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14",
]
];
$options = [];
//loop through the items
foreach ($items as $item) {
//set up the hashing key to use to locate if we hit dup entry
$key = "{$item['date']}-{$item['from_time']}-{$item['to_time']}";
//if indexing key not in options = never looked at it before
if (!array_key_exists($key, $options)) {
//have the key points to the current entry
$options[$key] = $item; //attach the whole item to it
//we want the id to be an array to initialize it to be one
$options[$key]['id'] = [];
}
//gets here then we know options[$key] exists
//if the item id not in the id array of our dict
if (!in_array($item['id'], $options[$key]['id'])) {
//add to it
$options[$key]['id'][] = $item['id'];
}
}
//array_values to get the values and not worry about the keys
print_r(array_values($options));
You can do something like this:
$arr = [
[
"id" => "1",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14"
],
[
"id" => "2",
"date" => "2021-08-03",
"from_time" => "09",
"to_time" => "14"
],
[
"id" => "3",
"date" => "2021-08-03",
"from_time" => "14",
"to_time" => "16"
]
];
$res = array_reduce($arr, function($carry, $entry) use(&$arr) {
$matches = array_filter($arr, function($item) use($entry) {
return $item['from_time'] === $entry['from_time'] && $item['to_time'] && $entry['to_time'];
});
//print_r([ $entry['id'], $matches ]);
foreach($matches as $match) {
unset($arr[array_search($match['id'], array_column($matches, 'id'))]);
}
if (!count($matches)) {
return $carry;
}
$carry[] = [
'id' => array_column($matches, 'id'),
'date' => $entry['date'],
'from_time' => $entry['from_time'],
'to_time' => $entry['to_time'],
];
return $carry;
}, []);
Related
This question already has answers here:
Filter/Remove rows where column value is found more than once in a multidimensional array
(4 answers)
Closed 10 months ago.
I have the following Associative Array below, and I wish to remove from the $filtered_results or $results the duplicated values based on the nid (number_id) field.
The solution I came up with, was to do a foreach loop, populate the new array with the key unique value that I wish and then return the array_values of that new array.
Is there a more elegant solution to tackle this problem ?
The order is irrelevant ( Replacing or keeping the current value);
Solution 1: Replacing the current value for the next.
$filtered_results = [];
foreach ($results as $k => $v) {
$filtered_results[ $v['nid'] ] = $v ;
}
return array_values ( $filtered_results ) ;
Solution 2: Keeping the first value found.
$filtered_results = [];
foreach ($results as $k => $v) {
if ( isset( $filtered_results[ $v['nid'] ] )) {
continue;
}
$filtered_results[ $v['nid'] ] = $v ;
}
Associative Array
$results = [
[
"date" => "2019-03-09",
"name" => "NameOne",
"phone" => "56784678",
"nid" => 1,
],
[
"date" => "2019-03-09",
"name" => "NameTwo",
"phone" => "123123123",
"nid" => 2,
],
[
"date" => "2019-03-09",
"name" => "NameThree",
"phone" => "6784568",
"nid" => 3,
],
[
"date" => "2019-03-09",
"name" => "NameFour",
"phone" => "90909090",
"nid" => 2,
],
[
"date" => "2019-03-09",
"name" => "NameFive",
"phone" => "3456356",
"nid" => 1,
],
];
Filtered Results
$filtered_results = [
[
"date" => "2019-03-09",
"name" => "NameThree",
"phone" => "6784568",
"nid" => 3,
],
[
"date" => "2019-03-09",
"name" => "NameFour",
"phone" => "90909090",
"nid" => 2,
],
[
"date" => "2019-03-09",
"name" => "NameFive",
"phone" => "3456356",
"nid" => 1,
],
]
Since is a duplicated question, the best solution I have found is :
array_values(array_column($results,NULL,'nid'))
Demo : https://onlinephp.io/c/fe78a
return array_intersect_key($results, array_unique(array_column($results, 'nid')));
use this :
$filtered_results = array_combine(array_column($results, 'nid'), $results);
I have an array with fields
[
"house" => "30|30|30",
"street" => "first|second|third",
...
]
I want to get array
[
[
"house" => "30",
"street" => "first",
...
],
[
"house" => "30",
"street" => "second",
...
],
[
"house" => "30",
"street" => "third",
...
]
]
I know how I can solve this using PHP and loop, but maybe this problem has more beautiful solution
use zip
$data = [
"house" => "30|30|30",
"street" => "first|second|third",
];
$house = collect(explode('|',$data['house']));
$street = collect(explode('|',$data['street']));
$out = $house->zip($street);
$out->toarray();
Here's something I managed to do with tinker.
$original = [
"house" => "30|30|30",
"street" => "first|second|third",
];
$new = []; // technically not needed. data_set will instantiate the variable if it doesn't exist.
foreach ($original as $field => $values) {
foreach (explode('|', $values) as $index => $value) {
data_set($new, "$index.$field", $value);
}
}
/* dump($new)
[
[
"house" => "30",
"street" => "first",
],
[
"house" => "30",
"street" => "second",
],
[
"house" => "30",
"street" => "third",
],
]
*/
I tried using collections, but the main problem is the original array's length is not equal to the resulting array's length, so map operations don't really work. I suppose you can still use each though.
$new = []; // Since $new is used inside a Closure, it must be declared.
collect([
"house" => "30|30|30",
"street" => "first|second|third",
...
])
->map(fn($i) => collect(explode('|', $i))
->each(function ($values, $field) use (&$new) {
$values->each(function ($value, $index) use ($field, &$new) {
data_set($new, "$index.$field", $value);
});
});
$array = ["house" => "30|30|30","street" => "first |second| third"];
foreach($array as $key=> $values){
$explodeval = explode('|',$values);
for($i=0; $i<count($explodeval); $i++){
$newarray[$i][$key]= $explodeval[$i];
}
}
output:
Array
(
[0] => Array
(
[house] => 30
[street] => first
)
[1] => Array
(
[house] => 30
[street] => second
)
[2] => Array
(
[house] => 30
[street] => third
)
)
I am having three arrays
topicsSelected
relavantGroups
topicAssingned
$topicsSelected = [ "T-100","T-600"];
$relavantGroups = [
[ "id" => "G-001","name" => "3 A","active" => false ],
["id" => "G-002","name" => "3 B","active" => false]
];
$topicAssingned = [
"G-001" => [
"groupID" => "G-001",
"groupName" => "3 A",
"topics" => [
"T-100" => [
"topicID" => "T-100"
],
"T-200" => [
"topicID" => "T-200"
]
]
],
"G-002" => [
"groupID" => "G-002",
"groupName" => "3 B",
"topics" => [
"T-400" => [
"topicID" => "T-400"
],
"T-500" => [
"topicID" => "T-500"
]
]
],
];
$topicsSelected array values at least one value should present $topicAssingned means based on groupID, i have to push one value to $relavantGroups like disable : D suppose value not present means disable : A
Expected output:
[
"id" => "G-001",
"name" => "3 A",
"active" => false,
"disable" => "D"
],
[
"id" => "G-002",
"name" => "3 B",
"active" => false,
"disable" => "A"
]
<?php
$topicsSelected = [ "T-100","T-600"];
$relavantGroups = [
[ "id" => "G-001","name" => "3 A","active" => false ],
["id" => "G-002","name" => "3 B","active" => false]
];
$topicAssigned = [
"G-001" => [
"groupID" => "G-001",
"groupName" => "3 A",
"topics" => [
"T-100" => [
"topicID" => "T-100"
],
"T-200" => [
"topicID" => "T-200"
]
]
],
"G-002" => [
"groupID" => "G-002",
"groupName" => "3 B",
"topics" => [
"T-400" => [
"topicID" => "T-400"
],
"T-500" => [
"topicID" => "T-500"
]
]
],
];
$topic_selected_map = [];
foreach($topicsSelected as $each_topic){
$topic_selected_map[$each_topic] = true;
}
$relevant_group_map = [];
foreach($relavantGroups as $each_group){
$relevant_group_map[$each_group['id']] = $each_group;
}
$result = [];
foreach($topicAssigned as $each_assigned_topic){
if(!isset($relevant_group_map[$each_assigned_topic['groupID']])) continue;
$topics_not_found = true;
foreach($each_assigned_topic['topics'] as $each_topic => $topic_details){
if(isset($topic_selected_map[$each_topic])){
$topics_not_found = false;
break;
}
}
$result[] = [
'id' => $each_assigned_topic['groupID'],
'name' => $each_assigned_topic['groupName'],
'active' => $relevant_group_map[$each_assigned_topic['groupID']]['active'],
'disable' => ($topics_not_found === true ? 'A' : 'D')
];
}
print_r($result);
Output:
Array
(
[0] => Array
(
[id] => G-001
[name] => 3 A
[active] => false
[disable] => D
)
[1] => Array
(
[id] => G-002
[name] => 3 B
[active] => false
[disable] => A
)
)
First, make a map(associative array) of values of $topicsSelected. Same goes for $relavantGroups. This is to make the check more efficient. See more on Hash Table.
Now, iterate over $topicAssigned and then iterate over each group's topics inside it. Now, check if a topic exists inside $topicsSelected using a simple isset function. If yes, we disable them, else we don't.
It's not very clear what you are asking and the code is a bit weird but I'll give it a try.
First fix your array declaration - you should use => and not :;
You have to Iterate over the $relavantGroups and for each element iterate the $topicAssingned array. Then perform a simple comparison to see if the group Id is present and you are done!
Here is my solution (quick and dirty): You can see it here
foreach ($relavantGroups as &$g) {
$found = false;
foreach ($topicAssingned as $key => $assigned) {
if ($key === $g["id"] && is_array($assigned["topics"])) {
foreach ($assigned["topics"] as $topic) {
if (in_array($topic["topicID"], $topicsSelected)) {
$found = true;
break;
}
}
}
}
$g["disable"] = $found ? "D" : "A";
}
var_dump($relavantGroups);
Updated the solution - note that I'm using in_array() to determine if the topicID is present. That mean that any value that is in the $topicsSelected array will affect the result.
Hope I helped.
This will output (based one your example):
array(2) {
[0]=> array(4) {
["id"]=> string(5) "G-001"
["name"]=> string(3) "3 A"
["active"]=> bool(false)
["disable"]=> string(1) "D"
}
[1]=> array(4) {
["id"]=> string(5) "G-002"
["name"]=> string(3) "3 B"
["active"]=> bool(false)
["disable"]=> string(1) "A"
}
}
Let say I have the datas in JSON,
3 people have different datas such as New only / New and Old / Old and New.
I tried using isset($_GET['NoID']); which is
http://localhost/test.php?NoID=31331 // Stan Lee
http://localhost/test.php?NoID=31332 // Mary Jane
http://localhost/test.php?NoID=31335 // John Doe
And the result are:
// Stan Lee
{
- Table: [
- {
Name: "Stan Lee",
NoID: "31331",
Type: "New",
- #attributes: {
id: "Table1",
rowOrder: "0",
}
},
]
}
// Mary Jane
{
- Table: [
- {
Name: "Mary Jane",
NoID: "31332",
Type: "New",
- #attributes: {
id: "Table1",
rowOrder: "0",
}
},
- {
Name: "Mary Jane",
NoID: "31333",
Type: "Old",
- #attributes: {
id: "Table2",
rowOrder: "1",
}
},
]
}
// John Doe
{
- Table: [
- {
Name: "John Doe",
NoID: "31334",
Type: "Old",
- #attributes: {
id: "Table1",
rowOrder: "0",
}
},
- {
Name: "John Doe",
NoID: "31335",
Type: "New",
- #attributes: {
id: "Table2",
rowOrder: "1",
}
},
]
}
I want to return which is condition is New only (Single row).
I tried to foreach() then strict statement for New and break, also I tried array_filter() and sort(). Those function didn't work out to return New only.
My code I tried so far:
foreach ($data['Table'] as $value) {
if (is_array($value) && $value['Type'] == "New") {
json($value);
break;
} elseif (is_string($value)) {
json($value);
break;
}
}
And the output is
Notice: Undefined index: Type
"New"
Both Mary Jane & John Doe gimme the right output, but Stan Lee didn't work.
Anyone can help me out?
Thank you!
hi bro i have checked you code and i just remove the break try this:
$data = ["Table" => [[
"Name" => "Stan Lee",
"NoID" => "31331",
"Type" => "New",
"attributes" =>[
"id"=>"Table1",
"rowOrder"=> "0"
]
],
[
"Name" => "Mary Jane",
"NoID" => "31332",
"Type" => "New",
"attributes" =>[
"id"=>"Table1",
"rowOrder" => "0"
]
],
[
"Name" => "Mary Jane",
"NoID" => "31333",
"Type" => "Old",
"attributes" =>[
"id"=>"Table2",
"rowOrder" =>"1"
]
],
[
"Name" => "John Doe",
"NoID" => "31334",
"Type" => "Old",
"attributes" =>[
"id"=>"Table1",
"rowOrder"=>"0"
]
],
[
"Name" => "John Doe",
"NoID" => "31335",
"Type" => "New",
"attributes" =>[
"id"=>"Table2",
"rowOrder" => "1"
]
],
]
];
foreach ($data['Table'] as $value) {
if (is_array($value) && $value['Type'] == "New") {
echo '<pre>';
print_r($value);
echo '</pre>';
} elseif (is_string($value)) {
echo '<pre>';
print_r($value);
echo '</pre>';
break;
}
}
and here is the output:
Array
(
[Name] => Stan Lee
[NoID] => 31331
[Type] => New
[attributes] => Array
(
[id] => Table1
[rowOrder] => 0
)
)
Array
(
[Name] => Mary Jane
[NoID] => 31332
[Type] => New
[attributes] => Array
(
[id] => Table1
[rowOrder] => 0
)
)
Array
(
[Name] => John Doe
[NoID] => 31335
[Type] => New
[attributes] => Array
(
[id] => Table2
[rowOrder] => 1
)
)
Let me know if this is what you need. feel free to ask.
Remove the break; from the foreach() loop.
break will interrupt the loop and no more array keys/values are treated anymore.
PHP break
edit
Probable you do not want to sent the json each time the condition is met.
So before the foreach() create variable $output and collect matched values to it $output[] = $value;. And finally send the whole output using json($output);
<?php
$data = [
"Table" => [
"Type" => "New"
],
[
1 => ["Type" => "New"],
2 => ["Type" => "Old"],
],
[
1 => ["Type" => "Old"],
2 => ["Type" => "New"],
]
];
foreach ($data['Table'] as $key => $value) {
If($key == 'Type' and $value == 'New'){
$output[] = $value;
}
Maybe this will help you:
$newArray = array();
foreach($data as $key => $d){
if(sizeof($d) > 1){
foreach($d as $key1 => $d1){
if(strtolower($d1['Type']) == 'new'){
$newArray[$key1]['Type'] = $d1['Type'];
}
}
}else{
if(strtolower($d['Type']) == 'new'){
$newArray[$key]['Type'] = $d['Type'];
}
}
}
print_r(json_encode($newArray));
Solution:
function arraySearch($array,$keyword="type",$value="New",$results=[]) {
foreach ( $array as $key => $val ) {
if(is_array($val)){
if(array_key_exists($keyword,$val)){
if ($val[$keyword] === $value ) {
$results[] = $key;
}
}else{
arraySearch($array,$keyword,$value,$results);
}
}
}
return json($results);
}
Call to function:
echo arraySearch($data['Table']);
Use array_filter like this, demo
array_filter($data, function($v){
return count($v) == 1 && $v['Type'] == 'New';
})
<?php
foreach ($data['Table'] as $value) {
foreach ($value as $data) {
if(in_array('New', $data)) {
//here you can code
echo "<pre>";
print_r($data);
}
}
}
Result: [{"0":"New","1":"New","4":"New"}]
<?php
$data = ["Table" => [[
"Name" => "Stan Lee",
"NoID" => "31331",
"Type" => "New",
"attributes" =>[
"id"=>"Table1",
"rowOrder"=> "0"
]
],
[
"Name" => "Mary Jane",
"NoID" => "31332",
"Type" => "New",
"attributes" =>[
"id"=>"Table1",
"rowOrder" => "0"
]
],
[
"Name" => "Mary Jane",
"NoID" => "31333",
"Type" => "Old",
"attributes" =>[
"id"=>"Table2",
"rowOrder" =>"1"
]
],
[
"Name" => "John Doe",
"NoID" => "31334",
"Type" => "Old",
"attributes" =>[
"id"=>"Table1",
"rowOrder"=>"0"
]
],
[
"Name" => "John Doe",
"NoID" => "31335",
"Type" => "New",
"attributes" =>[
"id"=>"Table2",
"rowOrder" => "1"
]
],
]
];
$build = [];
$output = [];
$i= 0;
foreach ($data as $value) {
foreach ( $value as $key => $val) {
if(!is_array($val) AND $val== "New"){
$build[$i][0] = $val;
$output = $build;
}else if(is_array($val) AND $val["Type"] === "New"){
$build[$i][$key] = "New";
$output = $build;
}
}
$i++;
}
print_r(json_encode($output));
?>
I have an array that looks like this
"name" => array:3 [
1 => "Hello"
4 => "Test"
21 => "Test2"
]
"runkm" => array:3 [
1 => "100.00"
4 => "1000.00"
21 => "2000.00"
]
"active" => array:3 [
1 => "1"
4 => "0"
21 => "0"
]
Can i somehow combine the matching keys with a PHP function so that the array would look like this instead
1 => array:3 [
name => "Hello"
runkm => "100.00"
active => "1"
]
4 => array:3 [
name => "Test"
runkm => "1000.00"
active => "0"
]
21 => array:3 [
name => "Test2"
runkm => "2000.00"
active => "0"
]
EDIT: Thanks for all the answers guys. What i was really looking for was a PHP built in function for this, which i probably should have been more clear about.
$newArr=array();
foreach($array1 as $key => $value){
$newArr[$key]=>array(
'name' =>$value[$key];
'runkm' =>$array2[$key];
'active'=>$array3[$key];
);
}
this is how you make a new array and then print the $newArr and check you get what you want or not? Good Luck!
<?php
$resultarr = array();
for($i=0;$i<count($sourcearr['name']);$i++) {
$resultarr[] = array('name'=>$sourcearr['name'][$i], 'runkm'=>$sourcearr['runkm'][$i], 'active'=>$sourcearr['active'][$i]);
}
This works well. And also, doesn't use hard coded keys.
<?php
$arr = [
"name" => [
1 => "Hello",
4 => "Test",
21 => "Test2"
],
"runkm" => [
1 => "100.00",
4 => "1000.00",
21 => "2000.00"
],
"active" => [
1 => "1",
4 => "0",
21 => "0"
]
];
// Pass the array to this function
function extractData($arr){
$newarr = array();
foreach ($arr as $key => $value) {
foreach($value as $k => $v) {
if(!isset($newarr[$k]))
$newarr[$k] = array();
$newarr[$k][$key] = $v;
}
}
return $newarr;
}
print_r(extractData($arr));
?>
I'm not sure if there's a function that does that in PHP but maybe you can try this
$arr1 = array(
"name" => array(
1 => "hello",
4 => "test",
21 => "test2",
),
"runKm" => array(
1 => "100",
4 => "200",
21 => "300",
),
"active" => array(
1 => "1",
4 => "0",
21 => "0",
),
);
// declare another that will hold the new structure of the array
$nArr = array();
foreach($arr1 as $key => $val) {
foreach($val as $sub_key => $sub_val) {
$nArr[$sub_key][$key] = $sub_val;
}
}
what this does is simply loop thru each array and its values and assign it to another array which is the $nArr. I hope it helps.