Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

PHP find string value and marked it by position in array

I have an array like this

array:32 [▼
  "ID" => "7917"
  "ProvinceCode" => "MB"
  "Create" => "2016-05-18 18:16:26.790"
  "DayOfTheWeek" => "4"
  "Giai1" => "28192"
  "Giai2" => "83509"
  "Giai3" => "51911-02858"
  "Giai4" => "14102-97270-96025-08465-89047-45904"
  "Giai5" => "7892-9140-4069-8499"
  "Giai6" => "6117-7471-5541-9119-4855-0566"
  "Giai7" => "843-860-023"
  "Giai8" => "71-13-55-89"
  "Giai9" => ""
  "Status" => "1"
]

I have a int variable $position = 59, and my job is find value by counting characters from Giai1 to Giai9 for 59 times count from 0 and get value of this position not include character -, so if $position = 59 then the getted value at position 58 will return.

For example, find value at position 20, the return is 1 at 14102 in Giai4 (actually 19 count from 0)

I've been wrote this code to do this

$position = 59;
$count = 0;
foreach ($data['result'][0] as $key => $item)
    {
        if(preg_match('@Giai@s', $key))
        {
            $_item = str_replace('-', '', $item);
            $count = $count + strlen($_item);

            $chars = str_split($item);
            $chars_sp = array_count_values($chars);

            $countChar = count($chars);
            if($count > $position)
            {
                //this block contains needed position
                $math = $count - $position;
                $secmath = strlen($_item) - $math;
                for($i=$secmath;$i>=0;$i--){
                    if($chars[$i] == '-'){
                        $splash_last++;
                    }
                }

                $secmath = $secmath + $splash_last;
                if($chars[$secmath] == '-'){
                    echo "+1 - ";
                    $secmath = $secmath + 1;
                }

                echo "Count: $count Match: $math Secmatch: $secmath Splash_last: $splash_last";
                $chars[$secmath] = 'x' . $chars[$secmath] . 'y';

                $edited = implode('', $chars);
                $data['result'][0][$key] = $edited;
                break;
            }
        }
    }

    dd($data['result'][0]);
}

Expected result will return this array with the mark of getted number. For example, code found number at position 59 (58 from 0) and signed it by x at first and y at end of value. You can see this in Giai5

//This is expected result
//Result array with mark of value at needed position

array:32 [▼
  "ID" => "7917"
  "ProvinceCode" => "MB"
  "Create" => "2016-05-18 18:16:26.790"
  "DayOfTheWeek" => "4"
  "Giai1" => "28192"
  "Giai2" => "83509"
  "Giai3" => "51911-02858"
  "Giai4" => "14102-97270-96025-08465-89047-45904"
  "Giai5" => "7892-9140-x4y069-8499"
  "Giai6" => "6117-7471-5541-9119-4855-0566"
  "Giai7" => "843-860-023"
  "Giai8" => "71-13-55-89"
  "Giai9" => ""
  "Status" => "1"
]

from 1 to 50 it works fine, but after position 50, the value of position I get is always wrong

Any idea?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If I understood you correctly this time, you can do something like this:

$array = [
    "ID" => "7917",
    "ProvinceCode" => "MB",
    "Create" => "2016-05-18 18:16:26.790",
    "DayOfTheWeek" => "4",
    "Giai1" => "28192",
    "Giai2" => "83509",
    "Giai3" => "51911-02858",
    "Giai4" => "14102-97270-96025-08465-89047-45904",
    "Giai5" => "7892-9140-4069-8499",
    "Giai6" => "6117-7471-5541-9119-4855-0566",
    "Giai7" => "843-860-023",
    "Giai8" => "71-13-55-89",
    "Giai9" => "",
    "Status" => "1"
];

$position = 59;

$start = 0;
$end = 0;

foreach ($array as $key => &$value) {
    if (!preg_match('/Giai/', $key)) {
        continue;    
    }

    $start = $end + 1;
    $end = $start + strlen(str_replace('-', '', $value)) - 1;

    if (($start <= $position) && ($position <= $end)) {
        $counter = $start;
        $value = str_split($value);

        foreach ($value as &$char) {
            if ($char === '-') {
                continue;
            }

            if ($counter === $position) {
                $char = "x{$char}y";
                break;
            }

            $counter++;
        }

        $value = join($value);
    }
}

var_dump($array);

Here is demo.

The code is a bit lengthy, but this is due to the fact that when you watch for the position you skip the dashes (-), but when you need to mark the character you have to take them into account. From this code you can understand the algorithm and then refactor code the way you want. I would suggest to escape from nested loops, as they are hard to read. You can do this by breaking code into functions or use the available array functions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...