<?php
// decide if 1 or 2 is better
function selectBestImage($image1, $image2) {
// fix for strange array_filter behaviour
if ($image1 === 0)
return $image2;
list($path1, $info1) = $image1;
list($path2, $info2) = $image2;
$width1 = $info1[0];
$width2 = $info2[0];
// ugly if-block :(
if ($width1 == 260) {
return $image1;
} elseif ($width2 == 260) {
return $image2;
} elseif ($width1 == 265) {
return $image1;
} elseif ($width2 == 265) {
return $image2;
} elseif ($width1 == 600) {
return $image1;
} elseif ($width2 == 600) {
return $image2;
} elseif ($width1 == 220) {
return $image1;
} elseif ($width2 == 220) {
return $image2;
} else {
// nothing applied, so both are suboptimal
// just return one of them
return $image1;
}
}
function getBestImage($images) {
// step 1: is the absolutley best solution present?
foreach ($images as $key => $image) {
if (strpos($image, '-large') !== false) {
// yes! take it and ignore the rest.
return $image;
}
}
// step 2: no best solution
// prepare image widths so we don't have to get them more than once
foreach ($images as $key => $image) {
$images[$key] = array($image, getImageInfo($image));
}
// step 3: filter based on width
$bestImage = array_reduce($images, 'selectBestImage');
// the [0] index is because we have an array of 2-index arrays - ($path, $info)
return $bestImage[0];
}
$images = array('image1.png', 'image-large.png', 'image-foo.png', ...);
$bestImage = getBestImage($images);
?>
Bu (i test etmedi) çalışması gerekir, ama suboptimaldir.
nasıl çalışır? Bir alt dizelerin arıyor (comparsion) ucuz olması nedeniyle ilk, biz, bu durumda, -large
, kesinlikle iyi sonuç için bakmak.
(! - yani biz bunları önceden hesaplamak daha pahalı) bir -large
görüntü bulmak yoksa biz görüntü genişlikleri analiz etmek gerekir.
array_reduce 2 dizi değerlerini alır ve işlevi tarafından bir dönüş (iyi bir) tarafından bu iki yerine bir filtreleme işlevini çağırır. dizideki geriye tek bir değer yoktur kadar bu tekrarlanır.
karşılaştırmalar (onlar ucuz bile) bir kez daha yapılır çünkü bu çözüm, hala suboptimaldir. benim büyük-O () notasyonu becerileri biraz (ha!) Paslı, ama ben O (n * logn) olduğunu düşünüyorum. soulmerges çözüm daha iyi bir - O (n) :)
İkinci döngü gerekli değildir, çünkü hala, soulmerges çözüm getirebileceği:
Eğer bir mola yerine dönüş var yani ilk, bir fonksiyonun içine paketi. İlk strstr eşleşirse, değerini döndürür ve geri kalanı görmezden. sonra, her dizi anahtar için puan saklamak zorunda değilsiniz. Sadece highestKey değişkene karşılaştırmak ve yeni değeri yüksek ise, saklayın.
<?php
function getBestImage($images) {
$highestScore = 0;
$highestPath = '';
foreach ($images as $image) {
if (strpos($image, '-large') !== false) {
return $image;
} else {
list($width) = getImageInfo($image);
if ($width == 260 && $highestScore < 5) {
$highestScore = 5;
$highestPath = $image;
} elseif ($width == 265 && $highestScore < 4) {
$highestScore = 4;
$highestPath = $image;
} elseif ($width == 600 && $highestScore < 3) {
$highestScore = 3;
$highestPath = $image;
} elseif ($width == 220 && $highestScore < 2) {
$highestScore = 2;
$highestPath = $image;
} elseif ($highestScore < 1) {
// the loser case
$highestScore = 1;
$highestPath = $image;
}
}
}
return $highestPath;
}
$bestImage = getBestImage($images);
?>
, test etmedi O (n) çalışması gerekir. daha hızlı, daha verimli bir şekilde atm hayal edemiyorum.