Skip to content

Instantly share code, notes, and snippets.

@kingkool68
Created April 4, 2020 03:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kingkool68/54856a6e923b602dd269e0a402362b93 to your computer and use it in GitHub Desktop.
Save kingkool68/54856a6e923b602dd269e0a402362b93 to your computer and use it in GitHub Desktop.
Take an array of values and interpolate missing numbers
<?php
function interpolate_row( $row = array() ) {
if ( ! is_array( $row ) || empty( $row ) ) {
return $row;
}
$items = array();
$item = array(
'start' => null,
'end' => null,
'empty_indexes' => array(),
);
foreach ( $row as $index => $current_val ) {
$prev_val = $row[ $index - 1 ];
$next_val = $row[ $index + 1 ];
if ( empty( $current_val ) && $current_val != '0' ) {
// Look behind
if ( ( ! empty( $prev_val ) || $prev_val == '0' ) && is_numeric( $prev_val ) ) {
$item['start'] = $prev_val + 0; // + 0 so PHP can do smart numeric type casting
}
// Look ahead
if ( ( ! empty( $next_val ) || $next_val == '0' ) && is_numeric( $next_val ) ) {
$item['end'] = $next_val + 0; // + 0 so PHP can do smart numeric type casting
}
$item['empty_indexes'][] = $index;
// If we have a start and end value we can reset for a new item
if (
( ! empty( $item['start'] ) || $item['start'] === 0 ) &&
( ! empty( $item['end'] ) || $item['end'] === 0 )
) {
$items[] = $item;
$item = array(
'start' => null,
'end' => null,
'empty_indexes' => array(),
);
}
// Bad data to interpolate, reset for a new item
if (
( empty( $item['start'] ) && $item['start'] !== 0 ) &&
( ! empty( $item['end'] ) || $item['end'] === 0 )
) {
$item = array(
'start' => null,
'end' => null,
'empty_indexes' => array(),
);
}
}
}
foreach ( $items as $item ) {
if ( $item['start'] === $item['end'] ) {
foreach ( $item['empty_indexes'] as $row_index ) {
$row[ $row_index ] = strval( $item['start'] );
}
} else {
$numerator = $item['end'] - $item['start'];
$divisor = count( $item['empty_indexes'] ) + 1;
$step = $numerator / $divisor;
foreach ( $item['empty_indexes'] as $index => $row_index ) {
$incremental_value = $step * ( $index + 1 );
$row[ $row_index ] = $item['start'] + $incremental_value;
$row[ $row_index ] = strval( $row[ $row_index ] );
}
}
}
return $row;
}
<?php
// Pass this to interpolate_row()
$input = array (
0 => 'foo',
1 => 'bar',
2 => '',
3 => '10',
4 => '',
5 => '',
6 => '40',
7 => '',
8 => '',
9 => '10',
10 => '5',
11 => '',
12 => '',
13 => '',
14 => '5',
15 => '0',
16 => '',
17 => '',
18 => '',
19 => '100',
20 => 'baz',
);
// This is the expected result
$result = array (
0 => 'foo',
1 => 'bar',
2 => '',
3 => '10',
4 => '20',
5 => '30',
6 => '40',
7 => '30',
8 => '20',
9 => '10',
10 => '5',
11 => '5',
12 => '5',
13 => '5',
14 => '5',
15 => '0',
16 => '25',
17 => '50',
18 => '75',
19 => '100',
20 => 'baz',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment