-1

I am trying to use the array_filter to filter for certain values and disallow the rest. I have never used array_filter before so I have been struggling with trying to wrap my heading around this.

Would I need to filter the values first before looping through it and if so how would I filter the array to look for only those values.

This is snippet of currently what I am working with and it is kicking back errors. $alerts is the values I need only to be returned from the array while disallowing the rest. Then I am looping through the filtered results. In my head this seems logical but I am sure I am missing something as it is not working.

$data = file_get_contents($url); // put the contents of the file into a variable
$results = json_decode($data, true); // decode the JSON feed

$alerts = array(Tornado Warning, Severe Thunderstorm Warning, Flash Flood Warning, Flood Warning);

$selected_events = array_filter($results['features'], function($data) {
        return $data === $alerts;
    });

//Lets loop through the array
foreach($selected_events as $currFeature)
{
    $event = $currFeature['properties']['event'];
    $wfo = $currFeature['properties']['sender'];
    $area = $currFeature['properties']['areaDesc'];
    $expires = $currFeature['properties']['expires'];

Here is an example of the JSON I am working with.

{
"@context": [
    "https://raw.githubusercontent.com/geojson/geojson-ld/master/contexts/geojson-base.jsonld",
    {
        "wx": "https://api.weather.gov/ontology#",
        "@vocab": "https://api.weather.gov/ontology#"
    }
],
"type": "FeatureCollection",
"features": [
    {
        "id": "https://api.weather.gov/alerts/NWS-IDP-PROD-2485744-2320592",
        "type": "Feature",
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [
                        -96.77,
                        33.84
                    ],
                    [
                        -96.76,
                        33.82
                    ],
                    [
                        -96.71,
                        33.83
                    ],
                    [
                        -96.52,
                        33.82
                    ],
                    [
                        -96.5,
                        33.77
                    ],
                    [
                        -96.43,
                        33.78
                    ],
                    [
                        -96.38,
                        33.73
                    ],
                    [
                        -96.39,
                        33.45
                    ],
                    [
                        -96.42,
                        33.46
                    ],
                    [
                        -96.94,
                        33.54
                    ],
                    [
                        -96.94,
                        33.85
                    ],
                    [
                        -96.77,
                        33.84
                    ]
                ]
            ]
        },
        "properties": {
            "@id": "https://api.weather.gov/alerts/NWS-IDP-PROD-2485744-2320592",
            "@type": "wx:Alert",
            "id": "NWS-IDP-PROD-2485744-2320592",
            "areaDesc": "Grayson",
            "geocode": {
                "UGC": [
                    "TXC181"
                ],
                "SAME": [
                    "048181"
                ]
            },
            "references": [],
            "sent": "2017-08-13T13:18:17+00:00",
            "effective": "2017-08-13T13:18:17+00:00",
            "onset": "2017-08-13T13:18:00+00:00",
            "expires": "2017-08-13T16:15:00+00:00",
            "ends": "2017-08-13T16:15:00+00:00",
            "status": "Actual",
            "messageType": "Alert",
            "category": "Met",
            "severity": "Severe",
            "certainty": "Likely",
            "urgency": "Expected",
            "event": "Flood Warning",
            "sender": "NWS Fort Worth TX",
            "headline": "Flood Warning issued August 13 at 8:18AM CDT expiring August 13 at 11:15AM CDT by NWS Fort Worth TX",
            "description": "The National Weather Service in Fort Worth has issued a\n\n* Flood Warning for...\nGrayson County in north central Texas...\n\n* Until 1115 AM CDT\n\n* At 816 AM CDT, Emergency management reported flooding of several\nroadways across Grayson County. While the heaviest rainfall has\nended...excessive runoff will continue to result in\nstreams...creeks and some rivers exceeding their banks across the\narea.\n\n* Some locations that will experience flooding include...\nSherman, Denison, Whitesboro, Howe, Pottsboro, Collinsville,\nWhitewright, Bells, Tom Bean, Knollwood, Dorchester, Eisenhower\nState Park, southeastern Lake Texoma, Southmayd, Sadler and Luella.",
            "instruction": "A Flood Warning means that flooding is imminent or occurring. Water\nrises will generally be gradual, but flooding of some low water\ncrossings and other low-lying areas near rivers, creeks, and streams\nis expected.",
            "response": "Avoid",
            "parameters": {
                "VTEC": [
                    "/O.NEW.KFWD.FA.W.0008.170813T1318Z-170813T1615Z/"
                ],
                "EAS-ORG": [
                    "WXR"
                ],
                "PIL": [
                    "FWDFLWFWD"
                ],
                "BLOCKCHANNEL": [
                    "CMAS",
                    "EAS",
                    "NWEM"
                ],
                "eventEndingTime": [
                    "2017-08-13T16:15:00Z"
                ]
            }
        }
    },
Texan78
  • 687
  • 2
  • 16
  • 42

1 Answers1

-1

The definition of your $alerts array is not correct in its present form. You should enclose the possible values in " or ', see my solution below.

You could do the following:

$o=json_decode($str,true); // $str is the JSON string
$features=$o['features'];
$filtered= array_filter($features,function($el){
    $alerts = array('Tornado Warning', 'Severe Thunderstorm Warning', 'Flash Flood Warning', 'Flood Warning');
    return in_array($el['properties']['event'],$alerts);});

json_encode(...,true) will produce an associative array (instead of an object). The filter function then checks for possible ['properties']['event'] properties of the elements in the array $features. Only those with values found in the $alerts array (I am using in_array() for this) will pass the filtering process.

If you prefer you can also define the $alerts array outside the actual filter function and only reference it there like:

..
...
$alerts = array('Tornado Warning', 'Severe Thunderstorm Warning',
                'Flash Flood Warning', 'Flood Warning');
$filtered= array_filter($features,function($el) use ($alerts) {
    return in_array($el['properties']['event'],$alerts);});

You can find a working demo here: http://rextester.com/EELE62798

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
  • I didn't down vote. I appreciate the response. It was most likely the other guy who retracted his answer who received 2 down votes. About the code it is giving me the following errors. str is undefined and array_filter() expects parameter 1 to be array, null which is referring to your last line of code starting with return in_array. – Texan78 Aug 13 '17 at 15:36
  • My `$str` should be the equivalent of your `$data`. I developed my solution on the basis of the rextester.com demo. So, as long as you have a valid JSON string in `$str`, my code will work. The JSON string you specified was actually missing a closing `]}` - see my demo too. – Carsten Massmann Aug 13 '17 at 15:40
  • Ah ok, yeah that makes sense for $str now. Oversight on my part and that makes sense. That also shined light on another problem I did. I had $data defined twice for two separate things. Here is the demo with the live JSON data. http://rextester.com/HGPOJ47232 – Texan78 Aug 13 '17 at 15:47
  • Hey, you can't simply `json_decode` a URL! You will have to get the actual contents of the site first. I don't think a simple `file_get_contents()` will work in this context. You might have to use CURL, as explained here: https://stackoverflow.com/a/12782109/2610061, but on rextester this does not work either (just tested it). However, that is a different question. You should post that separately if you continue to have problems with it. – Carsten Massmann Aug 13 '17 at 15:55
  • That URL is to the file on my domain. It is fetched from the API using cURL and then saved as a .json file on my server. It's been working perfectly looping through the array until I started added the array_filter. – Texan78 Aug 13 '17 at 16:04
  • Before looking at the `array_filter()`-stuff just make sure that you actually have got what you expect to get in `$data`. I. e. a text string that can be interpreted as JSON. The rest should then all into place. Sometimes when calling up files from a server they might be treated in different ways, according to their MIME type. – Carsten Massmann Aug 13 '17 at 16:24
  • Like I mentioned in my previous comment. It's been working perfect looping through the array until I started adding the array_filter. Did you happen to look at the URL? It is json. I am able to loop through it and create variables for the values I need. – Texan78 Aug 13 '17 at 17:01
  • Played around with this some more and got this working and works nicely and what I am looking for. Only issue now is that the keys under the "properties" object no longer have assigned variables since I don't have to loop through it like I was. How do I get those assign variables to the keys I am needing under that object I.E. properties -> event? – Texan78 Aug 13 '17 at 19:44