Как использовать функции, если я хочу переместить слово в конец массива в PHP? - PullRequest
0 голосов
/ 31 марта 2019

Привет, у меня есть такая таблица:

id | name
=============================
1  | blue house
-----------------------------
2  | house red
-----------------------------
3  | black house
-----------------------------
4  | car red
-----------------------------
5  | car black with driver
-----------------------------
6  | pink car
-----------------------------

Мне нужен вывод, как этот:

Blue house
Red house
Black house
Red car
Black with driver car
Pink car

Мне нужно, чтобы 'house' и 'car' двигались до конца, используя phpлогика.Я использовал функцию поиска и нажатия, но не в правильном направлении.Любая помощь?Спасибо :) мой код:

$conn=mysqli_connect('localhost','root','','shop') or die ("Fail");
$sql="select *  from products";
$result=mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
    while($row = mysqli_fetch_assoc($result)) {
        $names = array_search('house','car',$row,true);
        echo ($names[1]." ".$names[0]." ".$names[2]." ".$names[3]."<br>" );
    }
}

Ответы [ 3 ]

1 голос
/ 31 марта 2019

Просто с помощью preg_replace():

//while($row = mysqli_fetch_assoc($result)) { <!-- no longer needed

$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
//$rows = [['name'=>  'blue house'],['name'=>'car red'], [...]]
$words = ['house','car'];

print_r(preg_replace('/^('.implode('|', $words ).')\s(.+)$/i', '\2 \1', array_column($rows,'name')));

Код песочницы (для тестирования):

$rows = [
    ['name'=>  'blue house'],
    ['name'=>  'house red'],
    ['name'=>  'black house'],
    ['name'=>  'car red'],
    ['name'=>  'car black with driver'],
    ['name'=>  'pink car'],
];

$words = ['house','car'];

print_r(preg_replace('/^('.implode('|', $words ).')\s(.+)$/i', '\2 \1', array_column($rows,'name')));

выход

Array
(
    [0] => blue house
    [1] => red house
    [2] => black house
    [3] => red car
    [4] => black with driver car
    [5] => pink car
)

Песочница

Для верхнего регистра первая буква просто сделать это:

 print_r( array_map('ucfirst',preg_replace('/^('.implode('|', $words ).')\s(.+)$/i', '\2 \1', array_column($rows,'name'))) );

выход

Array
(
    [0] => Blue house
    [1] => Red house
    [2] => Black house
    [3] => Red car
    [4] => Black with driver car
    [5] => Pink car
)

Песочница

Просто используйте array_map() с ucfirst в качестве обратного вызова. Потому что, если вы получаете их из БД, если вас интересует регистр из источника, его легче прописать в SQL, например. SELECT LOWER(name) as name FROM .... Так, например, если Car red в верхнем регистре: проще получить его из БД, все ниже, потому что это избавит вас от написания пользовательского обратного вызова для array_map().

Регулярное выражение:

Поиск '/^('.implode('|', $words ).')\s(.+)$/i' или '/^(house|car)\s(.+)$/i'

  • ^ Начало строки
  • (...) Первая группа захвата
    • '.implode('|', $words ).' каждое слово отделяется | Или, например, house|car
  • \s Пробел, это первое слово, поэтому за ним всегда должно следовать одно
  • (...) Вторая группа захвата
    • .+ Совпадение с чем угодно
  • $ Соответствует концу строки
  • \i Флаг без учета регистра

Замените '\2 \1', просто переверните группы захвата.

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

Другие вещи, которые я здесь изменил: вы можете получить весь набор результатов, а затем использовать столбец массива, чтобы получить только столбец name. В PDO я мог бы сделать это с PdoStatement::fetchAll(PDO::FETCH_COLUMN) и не нуждаться в столбце массива, но я давно не использовал MySqli. Так что это был единственный способ, которым я мог думать.

И последнее: если это все, что вам нужно от БД, убедитесь, что выбрано только поле name. Это может улучшить производительность, потому что меньше данных передается из БД в PHP и т. Д ...

Ура!

0 голосов
/ 31 марта 2019
<code>    $arr=[
        'blue house',
        'house red',
        'black house',
        'car red',
        'car black with driver',
        'pink car'
    ];

    $move=['house','car'];

    foreach( $arr as $i => $row ){
        $elements=explode( ' ', $row );
        foreach( $move as $word ){
            if( in_array( $word, $elements ) ){
                $pos=array_search( $word, $elements );
                $elements[]=array_splice( $elements, $pos, 1 )[0];
            }
        }
        $arr[ $i ]=ucfirst( implode( ' ', $elements ) );
    }

    printf('<pre>%s
», print_r ($ обр, верно));

Выше будет выводиться:

Array
(
    [0] => Blue house
    [1] => Red house
    [2] => Black house
    [3] => Red car
    [4] => Black with driver car
    [5] => Pink car
)

или, с набором записей:

$move=['house','car'];

while( $row = mysqli_fetch_assoc( $result ) ) {
    $elements=explode( ' ', $row['name'] );
    foreach( $move as $word ){
        if( in_array( $word, $elements ) ){
            $pos=array_search( $word, $elements );
            $elements[]=array_splice( $elements, $pos, 1 );
        }
        echo ucfirst( implode( ' ', $elements ) );
    }

}
0 голосов
/ 31 марта 2019

Решением может быть, например:

while($row = mysqli_fetch_assoc($result)) {
    // explode `$row['name']` by space into 2 parts only
    $parts = explode(' ', $row['name'], 2);
    // if first part is "house" or "car" - output second part and then first
    if ($parts[0] === 'house' || $parts[0] === 'car') {
        echo $parts[1] . ' ' . $parts[0];
    } else {
        echo $row['name'];
    }
}
...