2012-06-26 3 views
1

Я пытаюсь найти ближайший продукт данного бюджетаПоиск имени массива значения, ближайшего к переменной?

$array = array(
    'productname1' => 5, 
    'productname2' => 10, 
    'productname3' => 15 
) 

$budget = 12; 

Я попытался с помощью функции, как следующее, чтобы найти ближайшее значение, но он возвращает только номер, который находится ближе всего к бюджету, а не название продукта.

function closest($array, $number) { 
     sort($array); 
     foreach ($array as $a) { 
      if ($a >= $number) return $a; 
     } 
     return end($array); 
    } 

Я не могу не думать о том, что есть более эффективная реализация этого. Любая помощь приветствуется.

+0

Вы хотите получить ближайшее предложение? Или первое значение, которое превышает значение? Поскольку с бюджетом 12, ближайшее значение - 10 - вам нужно проверить продукт с самой низкой разницей между бюджетом и ценой. – andrewsi

+0

@andrewsi Ближайшее в порядке. Я немного вводил в заблуждение от переменных, он не будет реализован, как он может появиться здесь. – MarkRobbo

ответ

3
foreach($array as $k => $v){ $diff[abs($v - $budget)] = $k; } 
ksort($diff, SORT_NUMERIC); 
$closest_key = current($diff); 

var_dump($closest_key);   // Product Name 
var_dump($array[$closest_key]); // Product Cost 

Печать:

 
    string(12) "productname2" 
    int(10) 

Или как функция:

function closest($array, $price) 
{ 
    foreach($array as $k => $v){ $diff[abs($v - $price)] = $k; } 
    ksort($diff, SORT_NUMERIC); 
    $closest_key = current($diff); 
    return array($closest_key, $array[$closest_key]); 
} 

print_r(closest($array, $budget)); 

распечатки:

 
    Array 
    (
     [0] => productname2 // Product Name 
     [1] => 10   // Product Price 
    ) 

Оба формата включает в себя только три шага:

  • Вычислить разницу между стоимостью продукта и бюджетом
  • Сортировать эти
  • Возьмите первый элемент из отсортированного массива (элемент, цена которого находится ближе всего к бюджету).

EDIT: Если вы не заботитесь ни о чем, кроме одного ближайшего продукта, то своего родом является излишеством и простой min() функция (например, используется Emil) была бы намного быстрее. Например:

function closest($array, $price) 
{ 
    foreach($array as $k => $v){ $diff[abs($v - $price)] = $k; } 
    $closest_key = $diff[min(array_keys($diff))]; 
    return array($closest_key, $array[$closest_key]); 
} 
+0

Лучшее из обоих миров, спасибо. – MarkRobbo

1
function closest($array, $number) { 
    sort($array); 
    foreach ($array as $name => $a) { 
     if ($a >= $number) return $name; 
    } 
    return end(array_keys($array)); 
} 

Хитрость приходит на этой линии:

foreach ($array as $name => $a) { 

Здесь вы назначаете $name к ключу массива и $a к значению массива. Поскольку вы хотите получить имя, return $name;

Кроме того, если совпадения не найдено, сделайте, end(array_keys($array)));, чтобы получить название продукта, иначе оно просто выплюнет значение, которое не то, что вы хотите.

1

Вы хотите вернуть ключ, а не значение:

function closest($array, $number) { 
    sort($array); 
    foreach ($array as $product=>$a) { 
     if ($a >= $number) return $product; 
    } 
    return $product; 
} 
1

Вот функциональный способ сделать это.

  1. Отсортировать каждое сообщение в зависимости от бюджета.
  2. Найти наименьшее значение.
  3. Отфильтруйте все продукты, не придерживаясь этого значения.

Реализация:

$diffs = array_map(function ($value) use ($budget) { 
        return abs($value - $budget); 
        }, $array); 

$smallest = min($diffs); 
$products = array_filter($array, 
         function ($value) use ($budget, $smallest) { 
          return abs($value - $budget) == $smallest; 
         }); 

$products теперь будет содержать все продукты, которые находятся ближе всего к бюджету.

Смежные вопросы