Сравнение n значений в одном массиве - PullRequest
0 голосов
/ 10 октября 2018

Итак, у меня есть ассоциативный массив, который выглядит следующим образом:

   #items: array:84 [
0 => {#513
  +"name": "Spencer, Heaney and Von"
  +"id": 49
  +"lon": 40.68
  +"lat": 90.25
  +"catId": 2
  +"locId": 49
  +"distance": 48.796277782319
}
1 => {#514
  +"name": "Yost-Terry"
  +"id": 16
  +"lon": 40.07
  +"lat": 90.99
  +"catId": 2
  +"locId": 16
  +"distance": 52.598218030179
}
2 => {#515
  +"name": "Mills-Okuneva"
  +"id": 98
  +"lon": 40.84
  +"lat": 89.79
  +"catId": 1
  +"locId": 98
  +"distance": 59.083838249165
}
3 => {#516
  +"name": "D'Amore Ltd"
  +"id": 67
  +"lon": 40.88
  +"lat": 89.82
  +"catId": 1
  +"locId": 67
  +"distance": 61.538239638491
}
4 => {#517
  +"name": "D'Amore Ltd"
  +"id": 67
  +"lon": 40.88
  +"lat": 89.82
  +"catId": 2
  +"locId": 67
  +"distance": 61.538239638491
}
5 => {#518
  +"name": "Kuvalis, Denesik and Terry"
  +"id": 14
  +"lon": 41.03
  +"lat": 90.05
  +"catId": 1
  +"locId": 14
  +"distance": 71.218957454573
}

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

Таким образом, в основном, если пользователь пропускает 4 категории, он берет первое имя местоположения, затем проверяет следующие 3 имени местоположения и проверяет, совпадают ли они, если так, то он добавляет все экземпляры местоположения с этим именем.в коллекцию.

(обратите внимание, что это данные, созданные мошенником, поэтому местоположение "Labadie-Bauch" не будет иметь одинаковый catId во всех 4 записях данных в реальном времени)

Следующий код - моя попыткапри решении этого, которое не работает.Я считаю, что это будет работать, если пользователь пропустит только 2 категории, но не будет, если он пройдет n категорий.

$final = collect();

dd($locations);
for($i = 0; $i < count($locations);$i++){
    for($j = 1; $j < count($request->categories);$j++){
        if($locations[$i]->name == $locations[$i+$j]->name){
            //add to final collection
        }
    }
}
dd($final);

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Это не очень приятное решение, поскольку оно включает в себя циклическое повторение данных три раза.

$locations = [/* ... */];
$categories = [1, 2];
$collection = [];

// Reduce locations to an array categories, grouped by location name
$grouped = array_reduce($locations, function ($grouped, $location) {
    $grouped[$location->name][] = $location->catId;
    return $grouped;
}, []);

// Filter the location groups to remove any locations that do not match all categories
$grouped = array_filter($grouped, function ($_categories) use ($categories) {
    return ! array_diff($categories, $_categories);
});

// Append locations with matching name and category to collection
foreach ($locations as $location) {
    if (isset($grouped[$location->name]) && in_array($location->catId, $categories)) {
        $collection[] = $location;
    }
}


var_dump($collection);

Вот рабочий пример: https://3v4l.org/mBZZn

Я заметил, что вы 'Вы используете Laravel, поэтому, если $locations в Collection, вы можете объединить некоторые из этой логики, используя доступные Collection методы.

0 голосов
/ 10 октября 2018

Я не совсем понимаю, чего вы пытаетесь достичь, однако вы можете попробовать объединить array_unique() с array_diff_key().Это даст вам список всех NON уникальных записей в массиве.

Что-то вроде:

array = array(
    1 => array('a', 'b', 'c', 'd'), 
    3 => array('a', 'b', 'c', 'd'), 
    4 => array('a', 'b', 'c', 'd'), 
    5 => array('d', 'e', 'f', 'g'), 
    6 => array('d', 'e', 'f', 'g'),
    7 => array('h', 'i', 'j', 'k')
);

$unique = array_unique($array, SORT_REGULAR);
$not_unique = array_diff_key($array, $unique);

уникальных возвращений:

array(3) {
  [1]=>
  array(4) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(1) "c"
    [3]=>
    string(1) "d"
  }
  [5]=>
  array(4) {
    [0]=>
    string(1) "d"
    [1]=>
    string(1) "e"
    [2]=>
    string(1) "f"
    [3]=>
    string(1) "g"
  }
  [7]=>
  array(4) {
    [0]=>
    string(1) "h"
    [1]=>
    string(1) "i"
    [2]=>
    string(1) "j"
    [3]=>
    string(1) "k"
  }
}

и возвращение not_unique:

array(3) {
  [3]=>
  array(4) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(1) "c"
    [3]=>
    string(1) "d"
  }
  [4]=>
  array(4) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(1) "c"
    [3]=>
    string(1) "d"
  }
  [6]=>
  array(4) {
    [0]=>
    string(1) "d"
    [1]=>
    string(1) "e"
    [2]=>
    string(1) "f"
    [3]=>
    string(1) "g"
  }
}

Вы можете объединить два массива, чтобы получить коллекцию из N экземпляров, и игнорировать отдельные записи.Обратите внимание на массив KEYS по результатам.Вы можете использовать их в своих интересах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...