Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
1

Проверить соседние значения многомерного массива на соответствие условию

15.01.2021, 20:54. Просмотров 534. Ответов 12
Метки нет (Все метки)

Доброго времени суток. Проверить чему равно одно значение массива просто. Понимаю как проверить соседние справа и слева значения. Но как проверить сверху и снизу? Попробую пояснить задачу на следующем примере. Есть многоуровневый массив типа:
PHP
1
2
3
4
5
6
7
8
9
10
11
$img = array( '1' => array('0','0','0','1', '1', '1','1', '1', '1', '1','1','1','1', '1', '1','1', '1', '1', '1'),
        '2' => array('1','1','1','1', '1', '1','1', '1', '1', '1','1','1','1', '1', '1','1', '1', '1', '1'),
        '3' => array('1','1','1','1', '1', '1','1', '1', '1', '1','1','1','1', '1', '1','1', '1', '1', '1'),
        '4' => array('1','1','1','1', '1', '1','0', '0', '0', '0','1','1','1', '1', '1','1', '1', '1', '1'),
        '5' => array('1','1','1','1', '1', '1','0', '0', '0', '0','1','1','1', '1', '1','1', '1', '1', '1'),
        '6' => array('1','1','1','1', '1', '1','0', '0', '0', '0','1','1','1', '1', '1','1', '1', '1', '1'),
        '7' => array('1','1','1','1', '1', '1','0', '0', '0', '0','1','1','1', '1', '1','1', '1', '1', '1'),
        '8' => array('1','1','1','1', '1', '1','0', '0', '0', '0','1','1','1', '1', '1','1', '1', '1', '1'),
        '9' => array('1','1','1','1', '1', '1','1', '1', '1', '1','1','1','1', '1', '1','1', '1', '1', '1'),
        '10' => array('1','1','1','1', '1', '1','1', '1', '1', '1','1','1','1', '1', '1','1', '1', '1', '1'),
        '11' => array('1','1','1','1', '1', '1','1', '1', '1', '1','1','1','1', '1', '1','1', '1', '1', '1'));
Нужно проверить принадлежит ли массиву, потом чему равны значения сверху, снизу, справа, слева (в любом порядке) и если соответствуют условию, то выполнить действие.
Можно проверить чему равно каждое значение этого массива напр так:
PHP
1
2
3
4
5
6
foreach($img as $key => $value){
    foreach ($value as $keyVal=>$val)
    {
      echo $value[$keyVal].'<br>';  // тут можно вставить проверку только для этого значения
    }
}
Соседние слева и справа более менее проверяются, даже немного получается пропускать те, что не входят в массив.
Можно было бы использовать array_key_exists но эта функция работает только в одномерном. Пробовал использовать var_dump(array_key_exists() но тоже полностью не получается.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.01.2021, 20:54
Ответы с готовыми решениями:

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

Проверка значения на соответствие условию и подстановка значения
Доброго дня. Вопрос. Как сделать так, что за 5 дн. до определённой даты (к примеру это 5...

Прибавить к дате количество дней и проверить результат на соответствие условию
Подскажите скрипт для vba или sql-запроса: Из таблицы нужно взять значение из поля типа дата...

Вывод по условию из многомерного массива
Приветствую, форумчане! Нуждаюсь в подсказке по работе с циклом foreach для разбора многомерного...

12
Эксперт PHP
4443 / 3619 / 1520
Регистрация: 24.04.2014
Сообщений: 10,665
15.01.2021, 21:32 2
Есть массив $img. Есть два индекса $key и $keyVal. Вокруг него будут $img[$key + 1][$keyVal] $img[$key - 1][$keyVal] $img[$key1][$keyVal + 1] $img[$key][$keyVal - 1], при условии что каждый индекс не выходит за пределы диапозона. Можно проверять индексы как на принадлежность диапозону, так и с помощью array_key_exists
0
1712 / 1038 / 386
Регистрация: 13.06.2013
Сообщений: 3,525
15.01.2021, 21:39 3
Варианты:
1) Если индексы числовые, то это просто +-1 что влево/вправо, что верх/вниз с проверках выхода из диапазона. Через for возможно красивее получиться.
2) Если индексы строковые, то можно завести дополнительные переменные, где будешь хранить предыдущие индексы.
3) Создать дополнительные два массива, которые будут хранить индексы исходных массивов. По этим массивам можно пробегаться циклом, легко делать +-1 сдвиги и получать индексы в исходных массивах.
0
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
15.01.2021, 22:06  [ТС] 4
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Вокруг него будут $img[$key + 1][$keyVal] $img[$key - 1][$keyVal] $img[$key1][$keyVal + 1] $img[$key][$keyVal - 1],
Вот их никак выстроить и не могу. Как вариант пробовал:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
foreach($img as $key => $value){
    foreach ($value as $keyVal=>$val)
    {
    if (!var_dump(array_key_exists($value[$keyVal-1], $value))||!var_dump(array_key_exists($value[$keyVal+1], $value))){
    echo 'W';
    }
        else
    {
      echo 'S<br>';
//    echo $value[$keyVal-1].'<br>';
    }
    }
}
Но вот как-то додумать до конца не могу

Добавлено через 3 минуты
Цитата Сообщение от tarasalk Посмотреть сообщение
Если индексы числовые
Могут быть всякие
Цитата Сообщение от tarasalk Посмотреть сообщение
Создать дополнительные два массива, которые будут хранить индексы исходных массивов. По этим массивам можно пробегаться циклом, легко делать +-1 сдвиги и получать индексы в исходных массивах.
Приблизительно понимаю, но не могу это реализовать

Добавлено через 3 минуты
Да, и проверять нужно на равенство значения 1 или 0
0
Эксперт PHP
4443 / 3619 / 1520
Регистрация: 24.04.2014
Сообщений: 10,665
15.01.2021, 22:14 5
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$arr = [
    [ 1,  2,  3,  4,  5],
    [ 6,  7,  8,  9, 10],
    [11, 12, 13, 14, 15],
    [16, 17, 18, 19, 20],
];
 
echo '<pre>';
foreach ($arr as $i => $a) {
    foreach ($a as $j => $v) {
        printf("I am (%d). My index is (%d, %d)\n", $v, $i, $j);
        
        if (array_key_exists($i-1, $arr)) {
            printf("Top element is (%d) with index (%d, %d)\n", $arr[$i-1][$j], $i-1, $j);
        } else {
            echo "I have no top element\n";
        }
        
        if (array_key_exists($j+1, $a)) {
            printf("Right element is (%d) with index (%d, %d)\n", $a[$j+1], $i, $j+1);
        } else {
            echo "I have no right element\n";
        }
        
        if (array_key_exists($i+1, $arr)) {
            printf("Bottom element is (%d) with index (%d, %d)\n", $arr[$i+1][$j], $i+1, $j);
        } else {
            echo "I have no bottom element\n";
        }
        
        if (array_key_exists($j-1, $a)) {
            printf("Left element is (%d) with index (%d, %d)\n", $a[$j-1], $i, $j-1);
        } else {
            echo "I have no Left element\n";
        }
        
        echo "\n\n--------------------\n\n";
    }
}
https://ideone.com/acDZZO
1
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
16.01.2021, 01:27  [ТС] 6
Цитата Сообщение от Jewbacabra Посмотреть сообщение
printf("I am (%d). My index is (%d, %d)\n", $v, $i, $j);
Никак не могу переделать ваш пример под свои нужды. Вообще стоит как бы несколько задач при проверке. Одна из них заменить все нули, вокруг которых есть единицы скажем на "Х". Я делаю так:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$new[] = '';
 
foreach ($arr as $i => $a) {
    foreach ($a as $j => $v) {
if ($v == '0'){
    if (array_key_exists($i-1, $arr)){ // проверка сверху
        if ($arr[$i-1][$j] == '1'){
            if (array_key_exists($j+1, $a)){ // проверка справа
                if ($a[$j+1] == '1'){
                    if (array_key_exists($i+1, $arr)){ // проверка снизу
                        if ($arr[$i+1][$j] == '1'){
                            if (array_key_exists($j-1, $a)){
                                if ($a[$j-1] == '1'){
                                    $new[]='Х';
                                    }else{$new[]='z';}
                                }else{$new[]='z';}
                            }else{$new[]='z';}
                        }else{$new[]='z';}
                    }else{$new[]='z';}
                }else{$new[]='z';}
            }else{$new[]='z';}
        }else{$new[]='z';}
    }else{$new[]='z';}
 
    }
}
echo count($new).'<br>';
echo '<pre>';
print_r($new);
echo '</pre>';
Оно то меняет, но при этом выдает предупреждение:
PHP
1
Warning: A non-numeric value encountered in F:\xampp\htdocs\sii1\bit4.php on line 29
И первый (тоесть нулевой) элемент получается пустым. И count($new) выходит на один больше исходного $arr.
0
Эксперт PHP
4443 / 3619 / 1520
Регистрация: 24.04.2014
Сообщений: 10,665
16.01.2021, 02:01 7

Не по теме:

не удержался

Кликните здесь для просмотра всего текста
Проверить соседние значения многомерного массива на соответствие условию



PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$arr = [
    [0, 1, 0, 0, 0],
    [1, 0, 1, 0, 0],
    [0, 1, 0, 1, 0],
    [0, 0, 1, 0, 0],
];
 
echo '<pre>';
echo "Before:\n\n";
echo implode(
    "\n",
    array_map(
        function ($a) { return implode('', $a); },
        $arr
    )
);
 
foreach ($arr as $i => &$a) {
    foreach ($a as $j => $v) {
        
        if (!array_key_exists($i-1, $arr) || $arr[$i-1][$j] !== 1) {
            continue;
        }
        
        if (!array_key_exists($j+1, $a) || $a[$j+1] !== 1) {
            continue;
        }
        
        if (!array_key_exists($i+1, $arr) || $arr[$i+1][$j] !== 1) {
            continue;
        }
        
        if (!array_key_exists($j-1, $a) || $a[$j-1] !== 1) {
            continue;
        }
        
        $arr[$i][$j] = 'X';
    }
}
unset($a);
 
echo
    "\n\nAfter:\n\n",
    implode(
        "\n",
        array_map(
            function ($a) { return implode('', $a); },
            $arr
        )
    );
https://ideone.com/cbm1Db
И по хорошему бы использовать for, чтоб боковые элементы не проверять
2
Эксперт PHP
4443 / 3619 / 1520
Регистрация: 24.04.2014
Сообщений: 10,665
16.01.2021, 02:07 8
Исправленный вариант
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$arr = [
    [0, 1, 0, 1, 0],
    [1, 0, 1, 1, 1],
    [0, 1, 0, 1, 0],
    [0, 0, 1, 0, 0],
];
 
echo '<pre>';
echo "Before:\n\n";
echo implode(
    "\n",
    array_map(
        function ($a) { return implode('', $a); },
        $arr
    )
);
 
foreach ($arr as $i => &$a) {
    foreach ($a as $j => $v) {
        if ($v !== 0) {
            continue;
        }
        
        if (!array_key_exists($i-1, $arr) || $arr[$i-1][$j] !== 1) {
            continue;
        }
        
        if (!array_key_exists($j+1, $a) || $a[$j+1] !== 1) {
            continue;
        }
        
        if (!array_key_exists($i+1, $arr) || $arr[$i+1][$j] !== 1) {
            continue;
        }
        
        if (!array_key_exists($j-1, $a) || $a[$j-1] !== 1) {
            continue;
        }
        
        $arr[$i][$j] = 'X';
    }
}
unset($a);
 
echo
    "\n\nAfter:\n\n",
    implode(
        "\n",
        array_map(
            function ($a) { return implode('', $a); },
            $arr
        )
    );
1
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
16.01.2021, 08:09  [ТС] 9
Цитата Сообщение от Jewbacabra Посмотреть сообщение
не удержался
)))) ну а как без этого? ))) На самом деле уже не знал как искать ошибку, отцентрировал, так сказать, думал каким-то образом пропускаю что-то когда располагаю на одном уровне. И это я ещё подчистил.
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Исправленный вариант
С моим массивом не работает
https://ideone.com/qblFmZ
0
Эксперт PHP
4443 / 3619 / 1520
Регистрация: 24.04.2014
Сообщений: 10,665
16.01.2021, 12:15 10
Цитата Сообщение от DyadyaGe Посмотреть сообщение
С моим массивом не работает
Во-первых индекс 'a'. Мой код именно для массива, структуры данных элементы которого расположены последовательно. Можно конечно и с произвольными индексами делать, благо в пхпшном масстве они будут именно в том порядке, которос их добавили, но зачем? Структуры данных подбирать чтобы решать задачу было проще, а не бороться с ними.
Чуть поправил код, сделал нормальные индексы и в условиях числа заменил на строки https://ideone.com/79tWvK
Во-вторых во входных данных виден квадрат из нулей. Если и его тоже надо заменить, то мой код этого делать не будет. Это уже более сложная задача.
1
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
16.01.2021, 14:48  [ТС] 11
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Во-первых индекс 'a'
Это я его случайно оставил, баловался с разными вариантами, и потом не заметил.
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Чуть поправил код
О, а я кручусь вокруг да около. Спасибо.
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Структуры данных подбирать чтобы решать задачу было проще, а не бороться с ними
Так у меня в задаче не понятно в каком виде будет подан массив. По идее с числовыми индексами, но вроде ограничений нет.
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Во-вторых во входных данных виден квадрат из нулей. Если и его тоже надо заменить, то мой код этого делать не будет. Это уже более сложная задача.
Если б только заменить все нули, то таких сложностей с проверкой по бокам не нужно было бы. Но вот следующая задача - поменять крайние нули в подобных квадратах.
Понимаю, что в таком виде пока менять не будет. Но надеюсь по аналогии усложнить и добиться замены крайних.
Есть ещё третья задача - находить дырки в таких квадратах/фигурах ))) Были мысли проверять это через массив. Создавать новый "квадратный" массив с максимальным "ребром" максимального вложенного массива или count "квадрата" и в нем аналогичным образом проверять, но уже для единиц. Может каким-то другим способом.

Добавлено через 8 минут
В спешке не дописал: максимального вложенного массива или count "квадрата" - имеется ввиду, что квадрата из нулей

Добавлено через 22 минуты
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Если и его тоже надо заменить, то мой код этого делать не будет. Это уже более сложная задача.
Кстати, думал сделать через добавление одного Elseif и Else. Сперва первой проверкой (вашей) проверить на окружение единицами, затем, как вторая крайность через Elseif - на окружение нулями, и потом все остальные через Else заменить на третью букву (цифру).
Думаю алгоритм правильный, а вот реализация пока страдает.
0
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
17.01.2021, 11:59  [ТС] 12
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Во-вторых во входных данных виден квадрат из нулей
Что-то не получается у меня заменить в этом квадрате три пары внутренних нулей. Если только заменить в условии проверку с единицы на нуль:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
foreach ($arr as $i => &$a) {
    foreach ($a as $j => $v) {
        if ($v !== '0') {
            continue;
        }
 
        if (!array_key_exists($i-1, $arr) || $arr[$i-1][$j] !== '0') {
            continue;
        }
 
        if (!array_key_exists($j+1, $a) || $a[$j+1] !== '0') {
            continue;
        }
 
        if (!array_key_exists($i+1, $arr) || $arr[$i+1][$j] !== '0') {
            continue;
        }
 
        if (!array_key_exists($j-1, $a) || $a[$j-1] !== '0') {
            continue;
        }
 
        $arr[$i][$j] = 'X';
    }
}
То закрашиваются только три нуля, по диагонали не пропускает из-за Х. Если же добавить и проверку на Х,
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
foreach ($arr as $i => &$a) {
    foreach ($a as $j => $v) {
        if ($v !== '0') {
            continue;
        }
 
        if (!array_key_exists($i-1, $arr) || $arr[$i-1][$j] !== '0'|| $arr[$i-1][$j] == 'X') {
            continue;
        }
 
        if (!array_key_exists($j+1, $a) || $a[$j+1] !== '0'|| $a[$j+1] == 'X') {
            continue;
        }
 
        if (!array_key_exists($i+1, $arr) || $arr[$i+1][$j] !== '0'|| $arr[$i+1][$j] == 'X') {
            continue;
        }
 
        if (!array_key_exists($j-1, $a) || $a[$j-1] !== '0'|| $a[$j-1] == 'X') {
            continue;
        }
 
        $arr[$i][$j] = 'X';
    }
}
То все равно ничего не помогает
https://ideone.com/MsfPpF
0
16 / 11 / 5
Регистрация: 04.04.2019
Сообщений: 380
18.01.2021, 01:55  [ТС] 13
Цитата Сообщение от Jewbacabra Посмотреть сообщение
Это уже более сложная задача
Сделал я почти все требования. Закрашивание одиночных нулей, закрашивание границ фигуры из нулей, закрашивание только внутренних, не касающихся единиц нулей фигуры.
https://ideone.com/9RwYss
Не могу придумать как объединить в массив единицы внутри фигуры из нулей.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.01.2021, 01:55

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Проверка каждого элемента массива, на соответствие условию
foreach (GameObject circle in circles) { if...

Бинарные деревья. Проверить на соответствие значения узлов дерева членам арифметической прогрессии
Как проверить на соответствие значения узлов дерева членам арифметической прогрессии. Я так...

Выбрать соседние значения из массива
Добрый день. В файл передается какое то значение, для примера 23. Выбираются значения из бд и...

Как получить нужные значения из многомерного массива?
Всем привет! Есть массив такого типа: данные1 ( =&gt; ученик ( =&gt; 4 =&gt;...

Из многомерного массива вытащить все значения в одномерный массив
Всем привет есть многомерный массив, мне нужно все эти значение поместить в один массив вот сам...

Проверка вводимого значения на соответствие индексу массива
Доброго времени суток, подскажите как реализовать работу поиска индекса по введенному значению....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.