Adding to another array with triming few characters from string - php

$data has
stdClass Object
(
[class] => srt-fields
[rules_field_1] => 1
[rules_condition_1] => 0
[rules_value_1] => text
[rules_field_2] => 3
[rules_condition_2] => 1
[rules_value_2] => another_text
...
)
Now I have another array $newdata, I need to have index $newdata['rules'] so that it should be something like:
$newdata['rules'] => array(
[field] => 1,
[condition] => 0,
[value] => text
),
array(
[field]=> 3,
[condition] =>1,
[value] => another_text
),
...
Thanks!

You could iterate over the properties of an object like an array:
$newdata['rules']=[];
foreach ($data as $key => $value) {
if (substr($key,0,6)=='rules_') {
// split key using '_'
$parts = explode('_',$key);
// get the 'name'
$name = $parts[1] ;
// get the index (-1 to be 0 based)
$idx = $parts[2] - 1;
// store data in new array
$newdata['rules'][$idx][$name] = $value;
}
}
print_r($newdata);
Outputs:
Array
(
[rules] => Array
(
[0] => Array
(
[field] => 1
[condition] => 0
[value] => text
)
[1] => Array
(
[field] => 3
[condition] => 1
[value] => another_text
)
)
)

Here is working code,
$data = [
"class" => "srt-fields",
"rules_field_1" => "1",
"rules_condition_1" => "0",
"rules_value_1" => "text",
"rules_field_2" => "3",
"rules_condition_2" => "1",
"rules_value_2" => "another_text",
];
$result = [];
foreach ($data as $k => $v) {
$num = filter_var($k, FILTER_SANITIZE_NUMBER_INT);
if (!empty($num)) {
$result['rules'][$num][(str_replace(['rules_', '_'], '', preg_replace('/[0-9]+/', '', $k)))] = $v;
}
}
$result['rules'] = array_values($result['rules']);
print_r($result);
str_replace — Replace all occurrences of the search string with the replacement string
filter_var — Filters a variable with a specified filter
preg_replace — Perform a regular expression search and replace
str_replace — Replace all occurrences of the search string with the replacement string
Here is working demo.

Definitely do not use regular expressions for this task -- because it is unnecessary resource overhead. Explode the keys on underscores, and use the individual components to construct the multi-level keys in your output array.
Code: (Demo)
$data = (object)[
"class" => "srt-fields",
"rules_field_1" => "1",
"rules_condition_1" => "0",
"rules_value_1" => "text",
"rules_field_2" => "3",
"rules_condition_2" => "1",
"rules_value_2" => "another_text"
];
foreach ($data as $key => $value) {
$bits = explode('_',$key); // this will produce a 1-element array from `class` and a 3-element array from others
if (isset($bits[2])) { // if element [2] exists, then process the qualifying data
$newdata[$bits[0]][$bits[2]-1][$bits[1]] = $value;
// ^^- make zero based
}
}
var_export($newdata);
Output:
array (
'rules' =>
array (
0 =>
array (
'field' => '1',
'condition' => '0',
'value' => 'text',
),
1 =>
array (
'field' => '3',
'condition' => '1',
'value' => 'another_text',
),
),
)
I am using -1 to make the output keys resemble a zero-based / indexed array. If your fields might not be consecutively ordered, you can remove the -1 and write $newdata['rules'] = array_values($newdata['rules']); after the loop.

$i = 0;
$j = 0;
foreach($data as $key=>$value){
if($j == 0)
{
$newdata['rules'][$i]['field'] = $value;
}
if($j == 1)
{
$newdata['rules'][$i]['condition'] = $value;
}
if($j == 2)
{
$newdata['rules'][$i]['value'] = $value;
$i++;
}
$j++;
if($j > 2)
{
$j = 0;
}
}
You can try this code. Please ignore syntax error as I have not tried this code but it should give you the result.

Related

PHP Get most repeated value in Array

I have an array within an array like this:
Array
(
[0] => Array
(
[name] => B
[id] => 924572
)
[1] => Array
(
[name] => A
[id] => 120689
)
[2] => Array
(
[name] => A
[id] => 120689
)
[3] => Array
(
[name] => C
[id] => 919644
)
[4] => Array
(
[name] => A
[id] => 120689
)
[5] => Array
(
[name] => B
[id] => 924572
)
)
How can I get the most repeated value from object named name and id?
I've already tried the code below but I'm getting an error: Warning: array_count_values(): Can only count STRING and INTEGER values!
$count = array_count_values($info);
arsort($count);
$popular = array_keys($count);
echo $popular[0];
Any fix regarding to this problem?
"Serializing way" for searching most repeated couples (name,id):
$out = array();
foreach($arr as $el){
$key = serialize($el);
if (!isset($out[$key]))
$out[$key]=1;
else
$out[$key]++;
}
arsort($out);
foreach($out as $el=>$count){
$item = unserialize($el);
echo "Name = ".$item['name'].' ID = '.$item['id'].' Count = '.$count.'<br/>';
}
Output:
Name = A ID = 120689 Count = 3
Name = B ID = 924572 Count = 2
Name = C ID = 919644 Count = 1
update Without loop
.....
arsort($out);
$most = unserialize(key($out));
$most_count = array_shift($out);
echo $most['name'];
echo $most['id'];
echo $most_count;
Output:
A
120689
3
A more linear solution.
$arr = Array
(
Array
(
"name" => "B",
"id" => 924572
),
Array
(
"name" => "A",
"id" => 120689
),
Array
(
"name" => "A" ,
"id" => 120689
),
Array
(
"name" => "C",
"id" => 919644
),
Array
(
"name" => "A",
"id" => 120689
),
Array
(
"name" => "B",
"id" => 924572
));
$countArr = Array();
for($i = 0; $i < count($arr); $i++)
{
$tmpArr = $arr[$i];
if(array_key_exists($tmpArr["name"],$countArr))
$countArr[$tmpArr["name"]]++;
else
$countArr[$tmpArr["name"]] = 0;
}
arsort($countArr);
var_dump($countArr);
Maybe you can work with this solution:
<?php
$info = array(
array(
"name" => "B",
"id" => 924572
),
array(
"name" => "A",
"id" => 120689
),
array(
"name" => "A",
"id" => 120689
),
array(
"name" => "C",
"id" => 919644
),
array(
"name" => "A",
"id" => 120689
),
array(
"name" => "B",
"id" => 924572
),
);
$result = array();
foreach ($info as $infoKey => $infoValue) {
foreach ($infoValue as $itemKey => $itemValue) {
if ($itemKey != "name") {
continue;
}
if (array_key_exists($itemValue, $result)){
$result[$itemValue]++;
continue;
}
$result[$itemValue] = 1;
}
}
arsort($result);
var_dump($result);
Will result in:
array (size=3)
'A' => int 3
'B' => int 2
'C' => int 1
Based on finding the mode and mapping in PHP. Would this work?
$name_array = array_map(function($x) {return $x["name"];}, $info);
$count = array_count_values($name_array);
$mode = array_keys($count, max($count));
To return an array of "name", "id" pairs use:
$return_value = array_filter($info, function($x) use ($mode) { return (in_array($x["name"], $mode));});
Makes use of array_column (requires PHP 5.5 or shim).
$count_values = array_count_values(array_column($array, 'name'));
$most_frequent_name = array_search(max($count_values), $count_values);
Then if you want all arrays with this name:
$items = array_filter($array, function ($v) use ($most_frequent_name) {
return $v['name'] == $most_frequent_name;
});
If several names may have the same top frequency:
$count_values = array_count_values(array_column($array, 'name'));
$most_frequent_names = array_keys($count_values, max($count_values));
$items = array_filter($array, function ($v) use ($most_frequent_names) {
return in_array($v['name'], $most_frequent_names);
});
Try following code. It will give you count of occurrences of all elements
function array_icount_values($arr,$lower=true) {
$arr2=array();
if(!is_array($arr['0'])){$arr=array($arr);}
foreach($arr as $k=> $v){
foreach($v as $v2){
if($lower==true) {$v2=strtolower($v2);}
if(!isset($arr2[$v2])){
$arr2[$v2]=1;
}else{
$arr2[$v2]++;
}
}
}
return $arr2;
}
$arr = array_icount_values($array);
echo "<pre>";
print_r($arr);

Count and remove duplicate arrays

I'm trying to count and remove duplicate arrays. To be a duplicate the entire array would have the match in keys and values with another.
Array
(
[0] => Array
(
[name] => Superman
[time] => 60
)
[1] => Array
(
[name] => Superman
[time] => 60
)
[2] => Array
(
[name] => Superman
[time] => 50
)
[3] => Array
(
[name] => Superman
[time] => 40
)
[4] => Array
(
[name] => Superman
[time] => 50
)
[5] => Array
(
[name] => Superman
[time] => 60
)
)
Into:
Array
(
[0] => Array
(
[name] => Superman
[time] => 60
[count] => 3
)
[1] => Array
(
[name] => Superman
[time] => 50
[count] => 2
)
[2] => Array
(
[name] => Superman
[time] => 40
)
)
I've come across this answer that can remove the duplicates, but I'm struggling to see how I may count them.
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
Quick and dirty, but you get exactly the data structure you asked for:
$data = array(
array("name" => "Superman", "time" => 60),
array("name" => "Superman", "time" => 60),
array("name" => "Superman", "time" => 50),
array("name" => "Superman", "time" => 40),
array("name" => "Superman", "time" => 50),
array("name" => "Superman", "time" => 60),
);
// count the occurrences
$occurrences = array();
for ($i = 0, $l = count($data); $i < $l; $i++) {
$serialized = serialize($data[$i]);
if (!isset($occurrences[$serialized])) {
$occurrences[$serialized] = 1;
}
else {
$occurrences[$serialized] = $occurrences[$serialized] + 1;
}
}
// get the wanted structure
$uniques = array();
foreach ($occurrences as $serialized => $count) {
$unserialized = unserialize($serialized);
if ($count > 1) {
$unserialized['count'] = $count;
}
$uniques[] = $unserialized;
}
print_r($uniques);
Not as compact as I would like, but it gets the job done:
function unserialize_unique_count($input, $k = 'count') {
$a = [];
foreach ($input as $d) {
$s = serialize($d);
$a[$s] = (isset($a[$s]) ? ($a[$s] + 1) : 1);
}
foreach ($a as $s => $c) {
$a[$s] = unserialize($s) + [ $k => $c ];
}
return array_values($a);
}
$grouped_with_count = unserialize_unique_count($input);
How it works: The first loop serializes and counts. The second unique merges. O(n).
How to use: Pass your multi-dimensional array as argument #1. Gives you back uniques with an additional key "count" that holds the count. If you want the count key to be something other than "count", pass the function a second argument.
You can use array_count_values in this case too. Example:
$values = array(
array('name' => 'Superman', 'time' => 60),
array('name' => 'Superman', 'time' => 60),
array('name' => 'Superman', 'time' => 50),
array('name' => 'Superman', 'time' => 40),
array('name' => 'Superman', 'time' => 50),
array('name' => 'Superman', 'time' => 60),
);
// map out into string then unique them
$uniques = array_map("unserialize", array_unique(array_map("serialize", $values)));
$count = array_count_values(array_map("serialize", $values)); // map out the arrays then get the counts
// then to merge the count
foreach($uniques as &$batch) {
foreach($count as $array => $v) {
if(unserialize($array) == $batch) { // if this particular key count is equal to this unique array, then push the count
$batch['count'] = $v;
}
}
}
echo '<pre>';
print_r($uniques);
Sample Output
Get Array and its values
make unique key on paypal_address
Use unique key to create temp array
Store all values with respective unique key in temp array
I am using time as unique key.
$tmpArr = Array();
$cnt = sizeof($arr);
for($i=0;$i<$cnt;$i++){
$time = $arr[$i]['time'];
if(!is_array($tmpArr[$time])){
$tmpArr[$time] = Array();
$tmpArr[$time]['count'] = 0;
}
$tmpArr[$time]['time'] = $arr[$i]['time'];
$tmpArr[$time]['name'] = $arr[$i]['name'];
$tmpArr[$time]['count'] = $tmpArr[$time]['count'] + 1;
}
print_r($tmpArr);
Note: Make changes in code according to your requirement

PHP Array duplicate data count

I have title and language data in PHP Array. I need to display repeated title count. Please check below array format.
Array (
[0] => Array ( [title] => My_title1 [language] => English )
[1] => Array ( [title] => My_title1 [language] => English )
[2] => Array ( [title] => My_title2 [language] => Japanese )
)
I need to display data in following format.
Title Language Count
My_title1 English 2
My_title2 Japanese 1
I tried following code
$count = array_count_values(array_map(
function($item) {
return $item['title'];
}, $testArray));
print_r($count);
but I got only title counts.
Array ( [My_title1] => 2 [My_title2] => 1 )
How do I display like following format?
Title Language Count
My_title1 English 2
My_title2 Japanese 1
You can do it for example this way:
<?php
$testArray = array (
0 => Array ( 'title' => 'My_title1', 'language' => 'English' ),
1 => Array ( 'title' => 'My_title1', 'language' => 'English' ),
2 => Array ( 'title' => 'My_title2', 'language' => 'Japanese' ),
);
$count = array_count_values(array_map(
function($item) {
return $item['title'].'#'.$item['language'];
}, $testArray));
$outArray = array();
foreach ($count as $k => $v) {
$k = explode('#', $k);
$record['Title'] = $k[0];
$record['Language'] = $k[1];
$record['Count'] = $v;
$outArray[] = $record;
}
var_dump($outArray);
Of course you need to use character that will not be used inside title and language, probably # is quite good enough
Try this code code which i created just for this assignment
<?php
$array = array(
0 => array ( 'title' => 'My_title1', 'language' => 'English'),
1 => array ( 'title' => 'My_title1', 'language' => 'English'),
2 => array ( 'title' => 'My_title2', 'language' => 'Japanese')
);
$final = array();
foreach($array as $key =>$value)
{
$flag = 0;
foreach($final as $key1 =>$value1)
{
if($array[$key]['title'] == $final[$key1]['title'])
{
$final[$key1]['count']++;
$flag = 1;
}
}
if($flag == 0)
{
$push = array('title' => $array[$key]['title'],'language' => $array[$key]['language'],'count' =>1);
array_push($final,$push);
}
}
echo "<pre>";print_r($final);

PHP Counting inside an Array

I want to create a list where if its already in the array to add to the value +1.
Current Output
[1] => Array
(
[source] => 397
[value] => 1
)
[2] => Array
(
[source] => 397
[value] => 1
)
[3] => Array
(
[source] => 1314
[value] => 1
)
What I want to Achieve
[1] => Array
(
[source] => 397
[value] => 2
)
[2] => Array
(
[source] => 1314
[value] => 1
)
My current dulled down PHP
foreach ($submissions as $timefix) {
//Start countng
$data = array(
'source' => $timefix['parent']['id'],
'value' => '1'
);
$dataJson[] = $data;
}
print_r($dataJson);
Simply use an associated array:
$dataJson = array();
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (!isset($dataJson[$id])) {
$dataJson[$id] = array('source' => $id, 'value' => 1);
} else {
$dataJson[$id]['value']++;
}
}
$dataJson = array_values($dataJson); // reset the keys - you don't nessesarily need this
This is not exactly your desired output, as the array keys are not preserved, but if it suits you, you could use the item ID as the array key. This would simplify your code to the point of not needing to loop through the already available results:
foreach ($submissions as $timefix) {
$id = $timefix['parent']['id'];
if (array_key_exists($id, $dataJson)) {
$dataJson[$id]["value"]++;
} else {
$dataJson[$id] = [
"source" => $id,
"value" => 1
];
}
}
print_r($dataJson);
You should simplify this for yourself. Something like:
<?
$res = Array();
foreach ($original as $item) {
if (!isset($res[$item['source']])) $res[$item['source']] = $item['value'];
else $res[$item['source']] += $item['value'];
}
?>
After this, you will have array $res which will be something like:
Array(
[397] => 2,
[1314] => 1
)
Then, if you really need the format specified, you can use something like:
<?
$final = Array();
foreach ($res as $source=>$value) $final[] = Array(
'source' => $source,
'value' => $value
);
?>
This code will do the counting and produce a $new array as described in your example.
$data = array(
array('source' => 397, 'value' => 1),
array('source' => 397, 'value' => 1),
array('source' => 1314, 'value' => 1),
);
$new = array();
foreach ($data as $item)
{
$source = $item['source'];
if (isset($new[$source]))
$new[$source]['value'] += $item['value'];
else
$new[$source] = $item;
}
$new = array_values($new);
PHP has a function called array_count_values for that. May be you can use it
Example:
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
Output:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)

counting occurence on multiple PHP array [duplicate]

This question already has answers here:
Count specific values in multidimensional array
(4 answers)
Closed 9 years ago.
I'm looking for a way to count occurence on an array of array.
This is my array :
Array
(
[0] => Array
(
[id] => 671
[title] => BIEND
[img] =>
[ville] => marseille
)
[1] => Array
(
[id] => 670
[title] => BIENC
[img] =>
[ville] => avignon
)
[2] => Array
(
[id] => 669
[title] => BIENB
[img] =>
[ville] => avignon
)
)
And what I would like to have :
Array
(
[avignon] => 2
[marseille] => 1
)
I tried with array_count_values, but it dont seems to be the good way.
Any idea?
You could just go through it manually:
$result = array();
foreach($input as $item)
{
$result[$item['ville']]++;
}
or, slightly nicer perhaps,
$result = array();
foreach($input as $item)
{
$city = $item['ville'];
if(!array_key_exists($city, $result)) {
$result[$city] = 1;
} else {
$result[$city]++;
}
}
Alternatively, you could do some array_map magic to first get an array with all the cities, and then use array_count_values as you planned:
$cities = array_count_values( array_map( function($a) { return $a['ville']; } ) );
Note, I haven't tested this last solution, I personally think the first one expresses the intention better. If you would like to use this one because it is shorter (i.e. less readable) I'll leave it to you to debug and comment it
You can use array_reduce():
$data = Array
(
0 => Array
(
'id' => 671,
'title' => 'BIEND',
'img' => '',
'ville' => 'marseille'
)
,
1 => Array
(
'id' => 670,
'title' => 'BIENC',
'img' => '',
'ville' => 'avignon'
)
,
2 => Array
(
'id' => 669,
'title' => 'BIENB',
'img' => '',
'ville' => 'avignon'
)
);
$result = array_reduce($data, function(&$cur, $x)
{
$cur[$x['ville']] = isset($cur[$x['ville']])?$cur[$x['ville']]+1:1;
return $cur;
}, []);
$my_array = array(...);
$result = array();
foreach ($my_array as $arr) {
$key = $arr['ville'];
if (! array_key_exists($key, $result){
$result[$key] = 1;
continue;
}
$result[$key] += 1;
}
I would write something like this. Array and subArray should be renamed according to their content.
$villes = array();
foreach($yourArray as $subArray) {
if(!in_array($subArray['ville'], $villes)) {
$villes[$subArray['ville']] = 1;
} else {
$villes[$subArray['ville']]++;
}
}
var_dump($villes);

Categories