Adrift
Adrift

Reputation: 59779

"Unsanitizing" elements within array

What I'm doing: I have a txt file with item #'s in it. I also have a directory of images that have these item #'s as prefixes of their file name but also have a few other string's (delimited by a -) after it, and then the file extension (.jpg).

The problem: The function I have works well, but the resultant array ($overlap) needs be in the format that the images originally had, because I'm going to write this array into a CSV file so I can import it. But in order to find the matches, I had to strip the original formatting on the image file names (so array_intersection() would work), but now I need to restore it.

Here is the current code:

function test() {

    function sanitize_items($value) {
        # Convert to uppercase, remove whitespace, then remove .JPG extension.
        # If the name has a "-", return the part before it.
        $base = basename( trim(strtoupper($value)), '.JPG' );
        $temp = explode('-', $base);
        return $temp[0];
    }

    $file = file('items.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    $img = scandir('img');

    $file = array_map('sanitize_items', $file);
    $img  = array_map('sanitize_items', $img);

    $overlap = array_intersect($file, $img);
    echo "<pre>";
    print_r($overlap); # returns the matches, but not in the format I need.
}

This is what $overlap currently returns:

Array
(
[0] => DEC308A
[1] => DEC308B
[2] => DEC309A
...
)

I need it to return the intersections but the way it was before sanitize_items() was ran:

Array
(
[0] => DEC308A-2020.jpg
[1] => DEC308B-2020.jpg
[2] => DEC309A-2300.jpg
...
)

Upvotes: 2

Views: 217

Answers (1)

Michael Berkowski
Michael Berkowski

Reputation: 270607

Instead of applying your sanitize function using array_map() (which can't preserve array keys), I would recommend doing a foreach() loop on both of the inputs to produce a new array which has the string like DEC308A as the associative array key, and the original full .jpg string as its value. You may then call array_intersect_key() across them to produce an intersection output which has both the shortened/sanitized string (in the key) and the original (in the value).

// Keep this function as it is...
function sanitize_items($value) {
    # Convert to uppercase, remove whitespace, then remove .JPG extension.
    # If the name has a "-", return the part before it.
    $base = basename( trim(strtoupper($value)), '.JPG' );
    $temp = explode('-', $base);
    return $temp[0];
}

$file = file('items.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$img = scandir('img');

// Temporary sanitized arrays:
$file_sanitized = array();
$img_sanitized = array();

// Loop over the input arrays and store them as key => value
// pairs, where the sanitized string is the key
foreach ($file as $f) {
  // Produces $file_sanitized['DEC308A'] = 'DEC308A-2020.jpg';
  $file_sanitized[sanitize_items($f)] = $f;
}
// Same kind of thing for $img...
foreach ($img as $i) {
  $img_sanitized[sanitize_items($i)] = $i;
}

// Now compare for intersection by key
$overlap = array_intersect_key($file_sanitized, $img_sanitized);

//-------------------------------- 
// Note, not sure of your inputs but you might need to reverse the args favoring
// $img_sanitized so you get those resultant values rather than what was in the file...
// $overlap = array_intersect_key($img_sanitized, $file_sanitized);

echo "<pre>";
print_r($overlap);

If you really want plain numeric keys at the end rather than strings like DEC308A, just call array_values() on it:

$overlap = array_values($overlap);

Upvotes: 3

Related Questions