Search code examples
phpoutputcomparisonarray-filter

PHP: filter array A according to array B


I make an Ajax call in order to filter the values from an array like this:

<?php

    $dataset = array_filter($_REQUEST['dataset'], function ($v){
        return filterArray($_REQUEST['keyword'], $v);
    });

    function filterArray($needle,$haystack){
        $needle = strtolower($needle);
        foreach($haystack as $v){
            if (stripos($v, $needle) !== false){
                return true;
            }
        };
    }
    echo json_encode($dataset, JSON_UNESCAPED_UNICODE);

?>

Thanks to the help of people around here, it works like a charm now.

However, I need something a little bit more sophisticated:

I have two nearly identical arrays imported to the php file via AJAX. Let's call them "cleanDataset" and "rawDataset".

They are basically clones but "rawDataset" is the original while "cleanDataset" is a copy, free of any html tag and undesired characters that I don't want to be part of the search. The differences are small but numerous and not predictable.

So, I would like to search "cleanDataset" against a selected keyword but I would like "rawDataset" to be filtered instead, accordingly, and returned to the javascript file.

Unfortunately, in the code here above, the array that is searched is also the one that would be filtered.

So basically, this is what I tried, which didn't work:

<?php

    $rawDataset = array_filter($_REQUEST['rawDataset'], function ($v){
        return filterArray($_REQUEST['keyword'], $_REQUEST['cleanDataset']);
    });

    function filterArray($needle,$haystack){
        $needle = strtolower($needle);
        foreach($haystack as $v){
            if (stripos($v, $needle) !== false){
                return true;
            }
        };
    }
    echo json_encode($rawDataset, JSON_UNESCAPED_UNICODE);

?>

I get a "jSon Parse error: unrecognized token '<'" message when trying to display the output array with console.log(). And apart from that, it seems to me that I ran very quickly out of options based on the little knowledge I have. There is no other place in the script I can think of where I can redirect the filtering from cleaDataset to rawDataset. I've searched online for a similar case but I couldn't find any.

Any help would be appreciated. Thank you.


Solution

  • Here is my suggestion. You can pass "external" variables to callback function via use keyword.

    Also array_filter() can pass element key along with value using ARRAY_FILTER_USE_BOTH flag

    Here I simplified code a bit to make it more readable, but essentially it should work and still shows my idea

    $keyword = 'abc';
    $cleanDataset = ['abcd', 'zabcd', 'awbcd', 'as abc d abc'];
    $rawDataset = ['abcd<br>', '<p>zabcd', '<strong>awbcd', 'as <code>abc</code> d abc'];
    
    $rawDataset = array_filter($rawDataset, function ($v, $k) use ($keyword, $cleanDataset) {
        return findWord($keyword, $cleanDataset[$k]);
    }, ARRAY_FILTER_USE_BOTH);
    
    function findWord($needle,$haystack){
        $needle = strtolower($needle);
        return (boolean) (stripos($haystack, $needle) !== false);
    }