PHP combine multiple arrays into multidimensional array - php

I am writing code in PHP to collect all the hashtags which I've used in all my media posts and see in how many posts I've used the hashtag and how many likes the post with that hashtag received in total.
I have collected all of the media posts in my database and are now able to export this information. Here is an example of the multidimensional array which is being output:
Array
(
[0] => Array
(
[id] => 1
[caption] => #londra #london #london_only #toplondonphoto #visitlondon #timeoutlondon #londres #london4all #thisislondon #mysecretlondon #awesomepix #passionpassport #shootermag #discoverearth #moodygrams #agameoftones #neverstopexploring #beautifuldestinations #artofvisuals #roamtheplanet #jaw_dropping_shots #fantastic_earth #visualsoflife #bdteam #nakedplanet #ourplanetdaily #earthfocus #awesome_earthpix #exploretocreate #londoneye
[likesCount] => 522
)
[1] => Array
(
[id] => 2
[caption] => #londra #london #london_only #toplondonphoto #visitlondon #timeoutlondon #londres #london4all #thisislondon #mysecretlondon #awesomepix #passionpassport #shootermag #discoverearth #moodygrams #agameoftones #neverstopexploring #beautifuldestinations #artofvisuals #roamtheplanet #jaw_dropping_shots #fantastic_earth #visualsoflife #bdteam #nakedplanet #ourplanetdaily #earthfocus #awesome_earthpix #harrods #LDN4ALL_One4All
[likesCount] => 1412
)
)
I am able to separate these hashtags out using the following function:
function getHashtags($string) {
$hashtags= FALSE;
preg_match_all("/(#\w+)/u", $string, $matches);
if ($matches) {
$hashtagsArray = array_count_values($matches[0]);
$hashtags = array_keys($hashtagsArray);
}
return $hashtags;
}
Now I want to create a multidimensional array for each hashtag which should look like this:
Array
(
[0] => Array
(
[hash] => #londra
[times_used] => 2
[total_likes] => 153
)
[1] => Array
(
[hash] => #london
[times_used] => 12
[total_likes] => 195
)
)
I am quite new to this and not sure how to achieve this. Help and suggestions are appreciated!

It would be easier to use the hashtags as keys in your array. You can
transform it later to your final format if you want to. The idea is to
traverse your input array and within each element iterate on the given
hashtags string, increasing counters.
And if your hashtags are always in a string like that, separated by
whitespace, you can also get an array of then with explode() or
preg_split() for finer control.
$posts = # your input array
$tags = [];
foreach ($posts as $post) {
$hashtags = explode(' ', $post['caption']);
foreach ($hashtags as $tag) {
if (!key_exists($tag, $tags)) {
# first time seeing this one, initialize an entry
$tags[$tag]['counter'] = 0;
$tags[$tag]['likes'] = 0;
}
$tags[$tag]['counter']++;
$tags[$tag]['likes'] += $post['likesCount'];
}
}
Transforming to something closer to your original request:
$result = array_map(function($hashtag, $data) {
return [
'hash' => $hashtag,
'times_used' => $data['counter'],
'total_likes' => $data['likes'],
'average_likes' => $data['likes'] / $data['counter'],
];
}, array_keys($tags), $tags);

Related

How to extract element inside an array, which in turn is inside a couple of arrays and display it using a foreach loop

I have a result of a query, which is the name of the image. I am storing the image names for every image Id in an array. Now, on the view page I am using foreach loop to display these images. The problem is I can't extract the elements(the name of the images) from this array.
My array is
Array ( [0] => Array ( [0] => Array ( [picture] => 5a3a13f237715637629.jpeg ) ) [1] => Array ( [0] => Array ( [picture] => 5a3b602654cfd527057.jpg ) ) )
I have used print_r and got this, now I want to extract only the 5a3a13f237715637629.jpeg values and display these using foreach loop on the view page. Any help is welcome.
The simplest way I can think of would be to json the array and then use regex to extract the filenames. You are then left with an array of filenames to loop through and display:
preg_match('/\w+.jpeg/', json_encode($array), $matches);
print_r($matches);
The benefits of doing it this way are that you don't need to know the structure of the array or go through embedded looping to find the values.
If you want do want the loop way; try this:
$array = array(
1 => array(
'picture' => '5a3a13f237715637629.jpeg'
),
2 => array(
'picture' => 'fnofweofweiofniewof.jpeg'
)
);
print_r(search_r($array, 'picture', $results));
function search_r($array, $key, &$results) {
if (!is_array($array)) {
return;
}
if (isset($array[$key])) {
$results[] = $array[$key];
}
foreach ($array as $subarray) {
search_r($subarray, $key, $results);
}
return $results;
}
That will result:
Array
(
[0] => 5a3a13f237715637629.jpeg
[1] => fnofweofweiofniewof.jpeg
)
PS. This is an adaption of this answer

searching for results in a multidimensional array and adding to a variable

I am having trouble sorting through a multidimensional array that I am pulling from an XML feed that can be different every time. I need to find something and place the result in a variable. I am still learning PHP and this unfortunately is a bit over my head.
I'll break down what I have. An example of my array contained in $valsarray:
Array
( [0] => Array
(
[tag] => GIVENNAME
[type] => complete
[level] => 8
[value] => peter
)
[1] => Array
(
[tag] => FAMILYNAME
[type] => complete
[level] => 8
[value] => rabbit
)
[2] => Array
(
[tag] => COMPLETENUMBER
[type] => complete
[level] => 9
[value] => 123-345-4567
)
[3] => Array
(
[tag] => URIID
[type] => complete
[level] => 9
[value] => customerEmail#gmail.com
)
)
Now I understand that I can get the result by using: $phone = $valsarray[2][value];
However, my problem is that if no phone number was given, the XML feed will not contain the phone number array so Array 3 would become Array 2.
So my question is how would I go about looping through the arrays to find if COMPLETENUMBER exists and then assigning the phone number contained in value to a $phone variable?
Here's one way:
$tags = array_column($valsarray, null, 'tag');
if(isset($tags['COMPLETENUMBER'])) {
$phone = $tags['COMPLETENUMBER']['value'];
}
Or if you only care about value:
$tags = array_column($valsarray, 'value', 'tag');
if(isset($tags['COMPLETENUMBER'])) {
$phone = $tags['COMPLETENUMBER'];
}
So in short:
Get an array of the value values indexed by tag
If COMPLETENUMBER index is set then get the value from value
After the array_column() you can then get whatever value you want:
$email = $tags['URIID'];
This loop would do it:
foreach($valsarray as $fieldArray)
{
if ($fieldArray['tag'] === 'COMPLETENUMBER')
{
$phone = $fieldArray['value'];
break;
}
}
If you need to do this type of thing repeatedly on the same array, you'd be better off reindexing it than searching each time. You could reindex like this:
foreach($valsarray as $key => $fieldArray)
{
$valsarray[$fieldArray['tag']] = $fieldArray;
unset($valsarray[$key]);
}
After reindexing it, you can do this for any field you want:
$phone = $valsarray['COMPLETENUMBER']['value'];
You can array_filter to get only COMPLETENUMBER entries, and set $phone if one is found.
$items = array_filter($valsarray, function($x) { return $x['tag'] == 'COMPLETENUMBER'; });
$phone = $items ? reset($items)['value'] : null;
Based on your other comments, if you want to get the values for a subset of tags from the array, you can use in_array in the array_filter callback. This could be wrapped in the array_column suggested in AbraCadaver's answer to get an array of values for any of the tags you're interested in:
$tags = ['COMPLETENUMBER', 'URIID'];
$data = array_column(array_filter($valsarray, function($x) use ($tags) {
return in_array($x['tag'], $tags);
}), 'value', 'tag');
The result would be like:
array (size=2)
'COMPLETENUMBER' => string '123-345-4567' (length=12)
'URIID' => string 'customerEmail#gmail.com' (length=23)

Search multidimensional array for value in certain key, return value of different key

I'm new to php and have been using the community and answers here to really help me with a little project I'm working on so thank you all in advance for the help so far!
I am pulling a load of information held in a poorly formatted text file/feed, trimming the contents of special characters and then using str_replace to find other specific strings and replace them with commas(,) or semi-colons(;), in order to create a usable piece of text. I then want to search this text for certain keywords and return other parts of the text in it's place.
So far, I've managed to explode the text into a multidimensional array, but I can't work out how to search this array now, in order to pull out a specific piece of information. I'm essentially trying to build a searchable array that I can pull information from as and when the original feed updates. Here's a sample of the array as it stands at the moment:
Array
(
[0] => Array
(
[0] => 240
[1] => 1
[2] => euro
[3] => 2016-02-19 15:30:00
[4] => EUR
)
[1] => Array
(
[0] => 240
[1] => 3
[2] => euro2
[3] => 2016-02-19 15:00:00
[4] => EUR
)
[2] => Array
(
[0] => 1890
[1] => 9
[2] => uspb
[3] => 2016-02-17 22:59:00
[4] => USD
)
)
Essentially, I want to be able to write something that will search this array for say uspb (array 2, key 2) and if it is found, return the value held under another key. So if I want key 0, it will return 1890. If I want key 1 when searching for euro2 it will return "3".
I've looked through a ton of examples and nothing really fits what I'm after at the moment. Perhaps I'm looking at this the wrong way and using an array isn't the correct approach. Any advice would be greatly appreciated.
For reference, here's a copy of my code (slight redacted) so far.
<?php
$file=file_get_contents("http://www.example.com/feed/");
$trim=trim($file, "[]");
$find = array("{\"value\":\"", "\",\"date_utc\":\"", "\",\"currency\":\"");
$replace = array(",", ",", "");
$replaced = str_replace($find, $replace, $trim);
$ret = array_map (
function ($_) {return explode (',', $_);},
explode (';', $replaced)
);
print_r ($ret);
?>
As your array is multidimensional - you have to iterate over it to find the value you need:
foreach ($ret as $value) {
// the index you want to search is always `2`?
if ($value[2] == 'uspb2') {
echo $value[0];
break;
}
}
And moving to function:
function findMyValue(
$array,
$search_key,
$search_str,
$key
) {
foreach ($array as $v) {
if ($v[$search_key] == $search_str) {
return $v[$key];
}
}
return 'NOT_FOUND';
}
echo findMyValue($ret, 2, 'euro', 1); // outputs 3
echo findMyValue($ret, 2, 'uspb', 0); // outputs 1890
And as already noticed in comments - it's not a poorly formated text, it's JSON. You can get an array from JSON string simply with json_decode function:
$file=file_get_contents("http://www.example.com/feed/");
$ret = json_decode($file, true);
var_dump($ret);

PHP Convert multidimensional array to match format of another

I have two arrays, one is generated by using explode() on a comma separated string and the other is generated from result_array() in Codeigniter.
The results when doing print_r are:
From explode():
Array
(
[0] => keyword
[1] => test
)
From database:
Array
(
[0] => Array
(
[name] => keyword
)
[1] => Array
(
[name] => test
)
)
I need them to match up so I can use array_diff(), what's the best way to get them to match? Is there something other than result_array() in CI to get a compatible array?
You could create a new array like this:
foreach($fromDatabase as $x)
{
$arr[] = $x['name'];
}
Now, you will have two one dim arrays and you can run array_dif.
$new_array = array();
foreach ($array1 as $line) {
$new_array[] = array('name' => $line);
}
print_r($new_array);
That should work for you.

PHP rewriting a json array (Undefined offset)

I'm taking some json, made by OpenLibrary.org, and remake a new array from the info.
Link to the OpenLibrary json
here is my PHP code to decode the json:
$barcode = "9781599953540";
function parseInfo($barcode) {
$url = "http://openlibrary.org/api/books?bibkeys=ISBN:" . $barcode . "&jscmd=data&format=json";
$contents = file_get_contents($url);
$json = json_decode($contents, true);
return $json;
}
the new array I'm trying to make looks something like this:
$newJsonArray = array($barcode, $isbn13, $isbn10, $openLibrary, $title, $subTitle, $publishData, $pagination, $author0, $author1, $author2, $author3, $imageLarge, $imageMedium, $imageSmall);
but when I try to get the ISBN_13 to save it to $isbn13, I get an error:
Notice: Undefined offset: 0 in ... on line 38
// Line 38
$isbn13 = $array[0]['identifiers']['isbn_13'];
And even if I try $array[1] ,[2], [3].... I get the same thing. What am I doning wrong here! O I know my Valuable names might not be the same, that's because they are in different functions.
Thanks for your help.
Your array is not indexed by integers, it is indexed by ISBN numbers:
Array
(
// This is the first level of array key!
[ISBN:9781599953540] => Array
(
[publishers] => Array
(
[0] => Array
(
[name] => Center Street
)
)
[pagination] => 376 p.
[subtitle] => the books of mortals
[title] => Forbidden
[url] => http://openlibrary.org/books/OL24997280M/Forbidden
[identifiers] => Array
(
[isbn_13] => Array
(
[0] => 9781599953540
)
[openlibrary] => Array
(
[0] => OL24997280M
)
So, you need to call it by the first ISBN, and the key isbn_13 is itself an array which you must access by element:
// Gets the first isbn_13 for this item:
$isbn13 = $array['ISBN:9781599953540']['identifiers']['isbn_13'][0];
Or if you need a loop over many of them:
foreach ($array as $isbn => $values) {
$current_isbn13 = $values['identifiers']['isbn_13'][0];
}
If you expect only one each time and must be able to get its key without knowing it ahead of time but don't want a loop, you can use array_keys():
// Get all ISBN keys:
$isbn_keys = array_keys($array);
// Pull the first one:
$your_item = $isbn_keys[0];
// And use it as your index to $array
$isbn13 = $array[$your_item]['identifiers']['isbn_13'][0];
If you have PHP 5.4, you can skip a step via array dereferencing!:
// PHP >= 5.4 only
$your_item = array_keys($array)[0];
$isbn13 = $array[$your_item]['identifiers']['isbn_13'][0];

Categories