使用子字符串搜索数组的有效方法

Efficient way to search array with substring

这是我的数组。

array (
  0 => 
  (object) array(
     'per_unit_price' => NULL,
     'code' => 'dynamic_labour_cost',
     'text_value' => '1000',
  ),
  1 => 
  (object) array(
     'per_unit_price' => NULL,
     'code' => 'dynamic_metal_weight',
     'text_value' => '10',
  ),
  2 => 
  (object) array(
     'per_unit_price' => NULL,
     'code' => 'dynamic_stone_carat',
     'text_value' => '10',
  ),
  3 => 
  (object) array(
     'per_unit_price' => NULL,
     'code' => 'dynamic_stone2_carat',
     'text_value' => '10',
  ),
  4 => 
  (object) array(
     'per_unit_price' => '10.00',
     'code' => 'dynamic_metal',
     'text_value' => NULL,
  ),
  5 => 
  (object) array(
     'per_unit_price' => '20.00',
     'code' => 'dynamic_stone',
     'text_value' => NULL,
  ),
  6 => 
  (object) array(
     'per_unit_price' => '50.00',
     'code' => 'dynamic_stone2',
     'text_value' => NULL,
  ),
)

简而言之,

举个例子吧=

我想乘以 => array[1]['text_value'] * array[4]['per_unit_price']

因为 array[1]['code'] = dynamic_metal_weightarray[4]['code'] = dynamic_metal

的子串

由于所有代码都是动态的,所以我不能硬编码条件。

我尝试使用 for each [扫描所有数组],但传统循环会花费很多时间。

请指导我。

正如@Chris Haas 所建议的,此解决方案基于相同的逻辑。根据我在下面的问题描述中看到的内容可以帮助您。还提供了即兴创作的建议..

<?php
echo "<pre>";
// array of data received from database
$code_values = [
    [
        'per_unit_price' => NULL,
        'code' => 'dynamic_labour_cost',
        'text_value' => '1000'
    ],
    [
        'per_unit_price' => NULL,
        'code' => 'dynamic_metal_weight',
        'text_value' => '10'
    ],
    [
        'per_unit_price' => NULL,
        'code' => 'dynamic_stone_carat',
        'text_value' => '10'
    ],
    [
        'per_unit_price' => NULL,
        'code' => 'dynamic_stone2_carat',
        'text_value' => '10'
    ],
    [
        'per_unit_price' => '10.00',
        'code' => 'dynamic_metal',
        'text_value' => NULL
    ],
    [
        'per_unit_price' => '20.00',
        'code' => 'dynamic_stone',
        'text_value' => NULL
    ],
    [
        'per_unit_price' => '50.00',
        'code' => 'dynamic_stone2',
        'text_value' => NULL
    ]
];

// filter $code_values to extract an array of elements where "per_unit_price" is set i.e. text_value is NULL
// Suggestion to improvise: If from database, you can fetch codes where only per_unit_price are set then this array_filter will not be required
$per_unit_prices = array_filter($code_values, function($array_element) {
    return is_null($array_element['text_value']);
});
// create array of per unit prices where code will be key and per_unit_price will be value
$per_unit_prices = array_column($per_unit_prices, 'per_unit_price', 'code');
echo "<br>per_unit_prices<br>";
print_r($per_unit_prices);

// filter $code_values to extract an array of elements where "text_value is set i.e. per_unit_price is NULL
// Suggestion to improvise: If you can fetch codes where only text_values are set then this array_filter will not be required
$text_values = array_filter($code_values, function($array_element) {
    return is_null($array_element['per_unit_price']);
});
// create array of text_values where code will be key and text_value will be value
$text_values = array_column($text_values, 'text_value', 'code');
echo "<br>text_values<br>";
print_r($text_values);

$output = []; // array to store multiplication of per_unit_price and text_value of matching elements
foreach($text_values as $code => $value) {
    // create key of per_unit_price by removing last string part starting with _
    $per_unit_prices_key = implode('_', array_slice(explode('_', $code), 0, -1));

    // check if per_unit_prices_key exits in $per_unit_prices array we created. If so, create output value
    if(isset($per_unit_prices[$per_unit_prices_key])) {
        $output[$code] = (float) $value * (float)$per_unit_prices[$per_unit_prices_key];
    }
}

echo "<br>output<br>";
print_r($output);

这是上面代码的输出。

per_unit_prices
Array
(
    [dynamic_metal] => 10.00
    [dynamic_stone] => 20.00
    [dynamic_stone2] => 50.00
)

text_values
Array
(
    [dynamic_labour_cost] => 1000
    [dynamic_metal_weight] => 10
    [dynamic_stone_carat] => 10
    [dynamic_stone2_carat] => 10
)

output
Array
(
    [dynamic_metal_weight] => 100
    [dynamic_stone_carat] => 200
    [dynamic_stone2_carat] => 500
)