<code class="php">$listData = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'], ... ];</code>
함수 정의, $listData 전달
111
의 요소가 222/333/444...의 요소와 중복되는 경우 false 반환222
의 요소인 경우, If 111/333/444...의 요소가 중복되면 false를 반환합니다.333
의 요소가 111/222/444...의 요소와 중복되면 false를 반환합니다.
..111/222/333/444의 요소가 반복되도록 허용하고 true를 반환합니다.
다른 경우에는 true를 반환합니다
알려짐:
$listData의 길이를 알 수 없습니다.
111/222/333/444의 길이를 알 수 없습니다.
111/222/333/444의 요소입니다. .. 문자는 문자열과 숫자입니다
직접 구현해봤는데 알고리즘이 형편없네요.
<code class="php">function test ($array) { $tempValueList = []; foreach ($array as $key => $valueList) { foreach ($valueList as $value) { $tempValueList[] = $key . '~' . $value; } } $result = true; foreach ($array as $key => $valueList) { foreach ($valueList as $value) { foreach ($tempValueList as $_value) { $pos = strpos($_value, '~'); $_key = substr($_value, 0, $pos); $_val = substr($_value, $pos + 1); if ($key == $_key) { continue; } if ($_val == $value) { $result = false; break 3; } } } } return $result; }</code>
<code class="php">$listData = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'], ... ];</code>
함수 정의, $listData 전달
111
의 요소가 222/333/444...의 요소와 중복되는 경우 false 반환222
의 요소인 경우, If 111/333/444...의 요소가 중복되면 false를 반환합니다.333
의 요소가 111/222/444...의 요소와 중복되면 false를 반환합니다.
..111/222/333/444의 요소가 반복되도록 허용하고 true를 반환합니다.
다른 경우에는 true를 반환합니다
알려짐:
$listData의 길이를 알 수 없습니다.
111/222/333/444의 길이를 알 수 없습니다.
111/222/333/444의 요소입니다. .. 문자는 문자열과 숫자입니다
직접 구현해봤는데 알고리즘이 형편없네요.
<code class="php">function test ($array) { $tempValueList = []; foreach ($array as $key => $valueList) { foreach ($valueList as $value) { $tempValueList[] = $key . '~' . $value; } } $result = true; foreach ($array as $key => $valueList) { foreach ($valueList as $value) { foreach ($tempValueList as $_value) { $pos = strpos($_value, '~'); $_key = substr($_value, 0, $pos); $_val = substr($_value, $pos + 1); if ($key == $_key) { continue; } if ($_val == $value) { $result = false; break 3; } } } } return $result; }</code>
살펴보니 앞의 두 답변은 사용할 수 없습니다. LZ는 정말 비참합니다. .
내가 정의한 하위 배열은 ['a', 'b', 'c', 'a']와 같은 단일 배열입니다.
내 답변:
<code>$result = array(); foreach ($listData as $line) { //子数组内部去重,再组装回原来的格式 $result[] = array_unique($line); } //子数组先去重再合并的结果数量 和 先合并子数组再去重的结果数量 做比较。 //如果是相同的,意味着不存在跨子数组的重复,只存在子数组内部重复,所以`True` var_dump(count(array_merge(...$result)) === count(array_unique(array_merge(...$listData))));</code>
내 대답은 시스템 함수를 더 많이 호출하고 더 단순해 보이지만 PHP array_xxx와 같은 함수의 대부분은 이러한 함수를 사용하지 않으면 상대적으로 작업 효율성이 향상될 수 있습니다.
현재는 @springhack이 가장 효율적입니다. 그리고 모든 상황에서 최대의 효율성을 유지할 수 있습니다.
이해하기 쉬운 보조 참고 정보:
원본 데이터:
<code>$listData = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'] ]; </code>
그러면 $result는 다음과 같이 됩니다.
<code>$listData = [ '111' => ['a', 'b', 'c'], '222' => ['d', 'e', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'] ]; </code>
하위 어레이 중복 제거 후 병합 결과
<code>Array ( [0] => a [1] => b [2] => c [3] => d [4] => e [5] => f [6] => b [7] => g [8] => h [9] => i [10] => j ) </code>
수량(배열 요소 수)을 위와 비교하는 데 사용되는 소위 "하위 배열을 먼저 병합한 후 중복 제거한 결과":
<code>Array ( [0] => a [1] => b [2] => c [4] => d [5] => e [6] => f [9] => g [10] => h [11] => i [12] => j )</code>
한 번 반복하여 현재 요소와 다른 모든 요소의 교차점을 찾습니다.
<code> function isExistsInOther($data) { $temp = []; $isExists = true; foreach ($data as $key=>$value) { $temp = $data; unset($temp[$key]); if(!$isExists) break; @array_walk($temp,function($v,$k) use($value,&$isExists){ if($isExists) { $intersect = array_intersect($v,$value); if(!empty($intersect)) { $isExists = false; } } }); } return $isExists; } $listData = [ '111' => ['a', 'k', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'e'], '444' => ['i', 'j'] ]; $result = isExistsInOther($listData); var_dump($result); //true 无交集 //false 有交集</code>
<code>/** * [checkRepeat 检查每个key的数组值是否与其它的有重复值] * @param [type] $listData [检查的数组] * @return [type] [array] */ function checkRepeat($listData) { foreach($listData as $key =>$val) { $check_arr = $listData; // 删除当前key unset($check_arr[$key]); // 合并删除后的数组 $check_arr = array_merge(...$check_arr); // 判断是否存在交集 $rs[$key] = count(array_intersect($val, $check_arr)) > 0 ? false : true ; } return $rs; } $listData = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'], ]; $rs = checkRepeat($listData);</code>
<code>function check($arr) { $chk = []; foreach ($arr as $k => $v) foreach ($v as $i) { if (isset($chk[$i] && $chk[$i] != $k) return false; $chk[$i] = $k; } return true; }</code>
클로 머신 코드 워드가 가장 효율적이므로 직접 디버깅할 수 있습니다.
위에 답변이 주어졌으므로 다차원 배열 중복 제거를 추가하겠습니다
<code>/** * 多维数组去重 * @param array * @return array */ function super_unique($array) { $result = array_map("unserialize", array_unique(array_map("serialize", $array))); foreach ($result as $key => $value) { if ( is_array($value) ) { $result[$key] = super_unique($value); } } return $result; }</code>
다차원 배열 중복 제거
<code>$listData = array_values($listData); foreach ($listData as $k => $v) { foreach ($listData as $n => $m) { if($k == $n) continue; if(array_intersect($v , $m)){ echo $k.$n.'false <br>'; } else{ echo $k.$n.'true <br>'; } } }</code>
내 대답(원리: 교차점 찾기를 반복):
<code><?php $list = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f','b'], '333' => ['g', 'h','c'], '444' => ['i', 'j'] ]; function jiaoji($array){ $listData = array_values($array); $list = []; for ($i = 0; $i < count($listData); $i++) { for ($j = $i+1; $j < count($listData); $j++) { $list[] = array_intersect($listData[$i],$listData[$j]); } } $result = array_filter($list); return count($result)==0; } var_dump(jiaoji($list));//bool(false) ?></code>
이렇게 이해가 되시나요? 이 배열의 값이 서로 교차하는 한 false가 반환됩니다. . .
array_intersect() 함수가 작동하는 것 같습니다. 그런데 문제는 배열의 값을 작은 배열로 변환하여 값을 전달하는 것입니다.
<code><?php $listData = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'], ... ]; function getArr($listData){ $isUnsetFirstKey = false; $len = count($listData); if($len<=1) return false; $firstKey = key($listData); $firstArr = array_unique($listData[$firstKey]); $newList = $listData; unset($newList[$firstKey]); foreach ($newList as $key => $val) { $arr = array_unique($val); $newarr = array_merge($firstArr,$arr); if(count($newarr) != count(array_unique($newarr))){ $isUnsetFirstKey = true; unset($newList[$key]); echo $key . "<br>"; } } if($isUnsetFirstKey) echo $firstKey . "<br>"; getArr($newList); } getArr($listData); ?></code>
1차원 배열은 2차원 배열과 유사합니다. 2차원 배열의 경우 다음 방법으로 건너뜁니다.
배열 길이 전후를 비교합니다. 배열 병합(그런 다음 고유한 값을 취함)
<code class="php">function check_repeat($arr){ $after_arr = []; // 对比自身 foreach($arr as $index => $value){ $arr[$index] = $after_arr = array_unique($value); if(count($value) !== count($after_arr)){ return true; } } // 对比其他 $temp = array_shift($arr); $cnt = count($temp); foreach ($arr as $index => $value) { $cnt += count($value); $temp = array_merge($temp, $value); } return $cnt !== count(array_unique($temp)) ? true : false; } $listData = [ '111' => ['a', 'b', 'c',], '222' => ['d', 'e', 'f',], '333' => ['g', 'h'], '444' => ['i', 'j'], ]; var_dump(check_repeat($listData)); </code>
<code>function test($listData) { $result = array_map('array_unique', $listData); foreach ($result as $key => $value) { $keys = array_values(array_diff(array_keys($result),[$key])); for($i = 0; $i <= count($keys); $i ++) { $data = array_merge_recursive($data,$result[$keys[$i]]); if ($i == (count($keys) -1) ) { $res = array_intersect($value, $data); } } $data = []; } return !empty($res) === true ? false : true; }</code>
<code><?php $listData = [ '111' => ['a', 'b', 'c', 'a'], '222' => ['d', 'e', 'f', 'f', 'b'], '333' => ['g', 'h'], '444' => ['i', 'j'], ]; $temp = array(); foreach ($listData as $key => $xxx) { foreach ($xxx as $value) { if (in_array($value, $temp)) { echo $value.' from '.$key.' is in array'; exit(); } } $temp = array_merge($temp, $xxx); } echo 'You should get a True!'; </code>
没几行,满足需求。
还原之前那个
shiji 的答案
先array_pop,取出最后一项。再取items数组的并集。if并集与最后一项有交集则返回true(表重复)。循环执行。
根据 @大呜 的算法改良了一下。
<code>function checkRepeat2($listData) { $check_arr = $listData; foreach ($listData as $key => $val) { //之前比较过的key无需再比较 unset($check_arr[$key]); if ($check_arr) { // 合并删除后的数组,判断是否存在交集 //As PHP 5.6 you can use array_merge + "splat" operator to reduce a bidimensonal array to a simple array: if (array_intersect($val, array_merge(...$check_arr))) { return false; } } } return true; }</code>
不知道是不是这样:
<code>$new_arr = []; foreach ($listData as $key => $value) { foreach ($value as $k => $v) { $kv = $k . $v; if (in_array($kv, $new_arr)) { echo '有重复';exit; } else { $new_arr[] = $kv; } } }</code>