Мне нужна помощь в написании логики скрипта php, который сортирует данные в определенный формат …
Во-первых, сценарий должен пройти через каждое значение s1 и пропинговать конечную точку, чтобы получить значения ml (более похожие), которые фактически ссылаются на другие записи s1. Это легкая часть! данные возвращаются вот так;
Table 1
s1 | ml
----------
1 | -
2 | 3,4
3 | 2,8,9
4 | -
5 | 2
6 | 1
7 | 10
8 | -
9 | -
10 | -
Состояние 1: Как видите, конечная точка возвращает данные для значения s1, сообщая, что другие записи s1 аналогичны другим, но направление ml не всегда является двунаправленным. иногда, например, когда s1 = 6, значение ml равно 1, однако, когда s1 = 1, значение ml отсутствует.
Состояние 2: Опять же, просто для объяснения записей ml, посмотрите выше и ниже, где s1 = 5 (выше) и где s1 = 2 + rec = 5 (ниже), этот скрипт должен понять, что для его значения уже есть запись s1 и что он должен быть добавленным там.
Состояние 3: Обратите внимание, что когда s1 = 2, ml = 3, это сохраняется, но когда s1 = 3, ml = 2, это игнорируется, потому что у нас есть обратная запись.
Я в основном хочу сопоставить все данные в 1 отсортированном «профиле», чтобы он оказался в следующем формате, который я буду хранить в другой таблице БД «отсортированных» записей.
Table 2
s1 | rec
----------
2 | 3
2 | 4
2 | 8
2 | 9
2 | 9
2 | 5
6 | 1
7 | 10
Уже несколько дней это ломает мне голову, мне нужно что-то эффективное, потому что в конце концов оно будет иметь дело с миллионами записей, и я уверен, что есть простое решение, но я просто не могу понять, как его запустить.
Я попробовал следующее, но я застрял и не знаю, как идти дальше;
public function getrelated($id='', $t=''){
if($id != ""){
$get = Easytest::where('s1','=',$id)->get();
if(count($get) > 0){
$ret= array();
foreach($get as $go){
$v = explode(",", $go->s2);
foreach ($v as $e) {
if($e != $t){
$ret[$e] = $this->getrelated($e, $id);
}
}
}
if(count($ret) > 0){
return $ret;
}else{
return "";
}
}else{
return $id;
}
}else{
return "";
}
}
public function easytest(){
ob_start();
$a = array(
array("s1"=>1,"s2"=>implode(",",array()).""),
array("s1"=>2,"s2"=>implode(",",array(3,4)).","),
array("s1"=>3,"s2"=>implode(",",array(2,8,9)).","),
array("s1"=>4,"s2"=>implode(",",array()).""),
array("s1"=>5,"s2"=>implode(",",array(2)).","),
array("s1"=>6,"s2"=>implode(",",array(1)).","),
array("s1"=>7,"s2"=>implode(",",array(10)).","),
array("s1"=>8,"s2"=>implode(",",array()).""),
array("s1"=>9,"s2"=>implode(",",array()).""),
array("s1"=>10,"s2"=>implode(",",array()).""),
array("s1"=>11,"s2"=>implode(",",array(12)).","),
array("s1"=>12,"s2"=>implode(",",array(2)).",")
);
//return Easytest::insert($a);
$records = Easytest::all();
foreach ($records as $record) {
$id = $record->s1;
echo "ROW: ".$id." > ";
$record->s2 = ltrim($record->s2,",");
$ml = explode(",",$record->s2);
if(count($ml) >= 1){
foreach ($ml as $t) {
echo "RESULT: ".$t." -".print_r($this->getrelated($t, $id), true);
echo ",\n";
}
}
echo " <br><br>\n\n";
}
return ob_get_clean();
}
Итак, я в конце концов решил это … по сути, это код ниже;
улучшения приветствуются 🙂
Вам нужно вызвать функцию так
related(array('searched'=>array(),'tosearch'=>array(13)));
функция:
public function related($input){$searched = $input['searched'];
$ar = array();
$bits = array();
if(count($input['tosearch']) != 0){
$get = Easytest::orWhere(function($query) use ($input)
{
foreach ($input['tosearch'] as $k=>$v) {
$query->orWhere('s2', 'LIKE', '%,'.$v.',%')->orWhere('s1', '=', $v);
}
})
->orderBy('s1', 'ASC')->get();
foreach ($input['tosearch'] as $k=>$v) {
unset($input['tosearch'][$k]);
$input['searched'][$v] = $v;
}foreach ($get as $result) {
$thesebits = explode(",", trim($result->s2,","));
foreach ($thesebits as $smallbit) {
if($smallbit != ""){
$bits[] = $smallbit;
}
}
$bits[] = $result->s1;
$bits = array_unique($bits);
foreach ($bits as $k=>$v) {
if(($key = array_search($v, $input['searched'])) == false) {
$input['tosearch'][$v] = $v;
}else{
unset($input['tosearch'][$v]);
}
}
$input['tosearch'] = array_unique($input['tosearch']);
}
return $this->related($input);
}else{
return $input;
}
}
Других решений пока нет …