phpの重複チェック

phpで配列の重複データをチェックして、重複しているデータを表示しようとしています。
foreach ($arry as $key => $value) {
$err_count = 0;
foreach ($arry as $key => $value2) {
if ($value == $value2) {
$err_count++;
if ($err_count >= 2) {
echo "重複".$value2;
}
}
}
}
としているのですが、
同じモノが2回表示されて困っています。
重複しているデータは一回だけ表示したいのですが、
なにか方法ないでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (6件)

>if ($value == $value2) {


この$valueと$value2の中身が文字列の場合「==」を使うのは駄目だよ。
>foreach ($arry as $key => $value) {
>foreach ($arry as $key => $value2) {
$keyを上書きする理由は?
普通なら
foreach ($arry as $key1 => $value) {
foreach ($arry as $key2 => $value2) {
としようよ

そもそも添字をを拾ってきているんだからそれを有効活用しないと。
「===」もしくはstrcmp()関数を使おうね。
それと
>if ($value == $value2) {
> $err_count++;
> if ($err_count >= 2) {
> echo "重複".$value2;
> }
>}
なんて変な書き方する?
ものすごく効率悪いと思わない?
if($value === $value2 && $key1!==$key2){
これ一つですむのでは?

それと何故「2」だけが全角?

この回答への補足

valueとkeyには別の名前が入っていたので、
こちらにのせるため変更したときに、混同してしまいました。
すみません。

例えば、(a,b,c,a)とデータがあった時に、
ひとつめのループが最初のaを、ふたつめのループがイコールで、
ヒットしたものをメッセージで出力します。
そして、ひとつめのループ最後のaに入った時、もう一度、
メッセージが表示されてしまうのですが。

補足日時:2011/04/16 17:43
    • good
    • 0

よく考えればユニークして差分をとるだけですね



<?
$arry=Array("a","b","a","c","b","a");
$arry2=array_unique(array_diff_assoc($arry,array_unique($arry)));
foreach($arry2 as $val) echo "重複".$val;
?>
    • good
    • 1

修正したら下記のようになります。



foreach (array_unique($arry) as $value) {
 $err_count = 0;
 foreach ($arry as $value2) {
  if ($value == $value2) {
   $err_count++;
  }
 }
 if ($err_count >= 2) {
  echo "重複".$value.PHP_EOL;
 }
}

書き直すと下記のようになります。

foreach (array_count_values($arry) as $key => $value) {
 if ($value >= 2) {
  echo "重複".$key.PHP_EOL;
 }
}
    • good
    • 0

重複データが3つ以上ある場合をどうするのでしょうか?



考え方としては、都度走査するか、チェッカーを使うのが妥当かと

<?
$arry=Array("a","b","c","a","b","a");
while(count($arry)){
$value=array_shift($arry);
if(array_search($value,$arry)) echo "重複".$value;
}
?>

<?
$arry=Array("x","y","z","x","z","x");
$check=Array();
foreach($arry as $value){
if(isset($check[$value])) echo "重複".$value;
else $check[$value]=true;
}

?>
    • good
    • 0

中々簡潔な手が思いつかず。

まぁ途中でキーを登録していってもいいけど、面倒くさそうだからなあ

http://ideone.com/jgb2R
    • good
    • 0

>ひとつめのループが最初のaを、ふたつめのループがイコールで、


>ヒットしたものをメッセージで出力します。
>そして、ひとつめのループ最後のaに入った時、もう一度、
>メッセージが表示されてしまうのですが。
アルゴリズムのヒント。
ゲームなんかの総当たりの対戦表や九九(全部ではなくて半分だけで行う方法)
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語で、他の関数で配列を書き換えられないようにしたい

下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。

main関数の側では配列aの中身を表示します。
しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。
 私はfunc関数以外では、この配列の中身をいじられたくないのです。
 なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。
 
 とは言ったものの、多分できないだろうなあ、という気がします。
 できないならばできないでも仕方ないのですが、確信が持てないのです。

条件があります。
funcでは表示は行なわない。
配列aの中身を表示できるように、funcから呼び出し元へ、aのアドレスまたはaの先頭要素のアドレスがわかるような情報を返す。


#include <stdio.h>

char *func(int i)
{
static char a[]="AAAA";
a[i]='z';
return a;
}

int main(void)
{
int i;
for(i=0; i<4; i++)
{
char *p=func(i);
/* p[i]='X'; ★配列の中身を書き換えてしまう。 */
puts(p);
}
return 0;
}

下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。

main関数の側では配列aの中身を表示します。
しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。
 私はfunc関数以外では、この配列の中身をいじられたくないのです。
 なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。
 
 とは言ったものの、多分できないだろうなあ、とい...続きを読む

Aベストアンサー

staticな変数を使う限りは無理な話です。

func内でnon-staticな領域にコピーしたものをreturnする。
仕様を明記し,funcを呼び出した先で別のバッファへコピーして使うよう徹底する。

などの対策をするしかないでしょう。
こういう仕様では,逆にfunc関数以外で使っていた文字列の内容が funcの呼び出しによって意図せず書き換えられてしまう,といった逆のパターンも往々にしてあります。要注意。

QPHP多次元配列で重複チェック

現在重複チェックのプログラムを制作中です。
各配列には400文字程度の文章で、75個あります。
条件文でのチェックを行うと通り数で2800通りになるので
array_count_values 関数
を使おうと思っているのですが
多次元配列にして、ラベル(bunsyou1~bunsyou75)と文章を一組にして、
ラベルで重複箇所を結果として出す方法は在りますでしょうか?
ご教示いただければ幸いです。

Aベストアンサー

まず、例示の命題は多次元ではないですよね?

あとは、前回書いたとおりソートしてしまえば、前後2項目の
比較を繰り返すだけです。

<?
$bunsyoulist = array(
"bunsyou1" => "xxx"
,"bunsyou2" => "aaa"
, "bunsyou3" => "bbb"
, "bunsyou4" => "xxx"
, "bunsyou5" => "ccc"
, "bunsyou6" => "xxx"
, "bunsyou7" => "aaa"
, "bunsyou8" => "xxx"
);
asort($bunsyoulist);
$preval="";
$prekey="";
foreach ($bunsyoulist as $key =>$val){
if($preval==$val){print $prekey." = ".$key."<br>";}
$preval=$val;
$prekey=$key;
}
?>

まず、例示の命題は多次元ではないですよね?

あとは、前回書いたとおりソートしてしまえば、前後2項目の
比較を繰り返すだけです。

<?
$bunsyoulist = array(
"bunsyou1" => "xxx"
,"bunsyou2" => "aaa"
, "bunsyou3" => "bbb"
, "bunsyou4" => "xxx"
, "bunsyou5" => "ccc"
, "bunsyou6" => "xxx"
, "bunsyou7" => "aaa"
, "bunsyou8" => "xxx"
);
asort($bunsyoulist);
$preval="";
$prekey="";
foreach ($bunsyoulist as $key =>$val){
if($preval==$val){print $...続きを読む

Qエクセルの配列関数の制限について

エクセルの配列関数の制限について


V列にX列・Y列・Z列・AA列・AB列・AC列・AE列・AG列・P列を参照した配列関数を
下のように入力しています。

{=SUM((Y$1:Y$500=F7)*(Z$1:Z$500=H7)*(AA$1:AA$500)*(P7="○"),(AB$1:AB$500=F7)
*(AC$1:AC$500=H7)*(AE$1:AE$500=H7)*(AG$1:AG$500)*(P7="×"))}

このY列・Z列・AA列・AB列・AC列・AE列・AG列は、ぞれぞれ200行くらいしか
文字が入力されていない場合には、配列関数の結果がうまく表示されました。


これらのセルの200行以降から300行・400行と項目を増やしていったところ、
配列関数の結果がうまく表示されないセルが出てきました。


これは、配列関数の参照するセルに制限があるということでしょうか?

Aベストアンサー

>SUMPRODUCT関数でも同様に0が表示されました。

F9キーで再計算しても「0」と表示されるなら、集計対象のセルがないということです。

>配列数式の結果で0が表示された件について、Y列・Z列の文字に半角と全角の括弧
「()」と「()」が混在していたことが原因と判明しました!

この意味が不明ですが(仮に混在しているとしても「0」と表示されることはない)、今回の「0」が表示される原因は解明できたということでしょうか?

>再計算されるまでに10分~15分かかり、メールやインターネットや他のエクセルなどが
使用できずに固まってしまいます。そのため、手動で再計算されるようにして何とか
使用しています。

再計算に1分以上かかることはほとんど考えられないのですが、いずれにしろ今回のようなデータ範囲の広い配列数式を多数入力するのは全く実用に堪えないと思いますので、数式部分を適宜「値」化して(古いデータを修正する場合は必要に応じて計算式を少しずつオートフィルする)、必要最小限の数式だけを残して作業することをお勧めします(VBAを使用しても計算に時間がかかる可能性が高いと思います)。

>SUMPRODUCT関数でも同様に0が表示されました。

F9キーで再計算しても「0」と表示されるなら、集計対象のセルがないということです。

>配列数式の結果で0が表示された件について、Y列・Z列の文字に半角と全角の括弧
「()」と「()」が混在していたことが原因と判明しました!

この意味が不明ですが(仮に混在しているとしても「0」と表示されることはない)、今回の「0」が表示される原因は解明できたということでしょうか?

>再計算されるまでに10分~15分かかり、メールやインターネットや他のエク...続きを読む

QPHP&MySQL fetchAll()でデータを取得している時に、重複している箇所を除外するには?

MySQLに接続して、下記のようにデータ(id,名前, 時間)を新しい順に $rows = $stmt->fetchAll(); で取得しているときに、

Array
(
[0] => Array
(
[id] => 8
[name] => 山田
[time] => 2016-05-03 17:25:36
)
[1] => Array
(
[id] => 9
[name] => 田中
[time] => 2016-05-03 17:25:28
)

[2] => Array
(
[id] => 8
[name] => 山田
[time] => 2016-05-03 17:24:16
)

[3] => Array
(
[id] => 9
[name] => 田中
[time] => 2016-05-03 17:24:06
)

[4] => Array
(
[id] => 200
[name] => 西野
[time] => 2016-05-03 17:20:21
)

[5] => Array
(
[id] => 10
[name] => 武田
[time] => 2016-05-03 17:02:30
)

)

HTMLで下記のように出力します。

<ul>
<?php foreach ($rows as $row) { ?>
<li> <php ehco $row['id']; ?> "> <?php echo $row['name']; ?> </li>
<?php } ?>
</ul>

↑ ただこの場合は、

・8 山田
・9 田中
・8 山田
・9 田中
・200 西野
・10 武田

と表示されます。
8 山田 と 9田中は 2回登場するので、同じidが複数登場する場合は、時間が新しい方の行だけのこして、古いほうを非表示にしたいのですがどうすればよいでしょうか?

array unique()関数で粘ってみたのですが、やり方がまずいのか、できなかったので、教えてください。または、他のやり方もあるかもしれません。よろしくお願いします。

MySQLに接続して、下記のようにデータ(id,名前, 時間)を新しい順に $rows = $stmt->fetchAll(); で取得しているときに、

Array
(
[0] => Array
(
[id] => 8
[name] => 山田
[time] => 2016-05-03 17:25:36
)
[1] => Array
(
[id] => 9
[name] => 田中
[time] => 2016-05-03 17:25:28
)

[2] => Array
(
[id] => 8
[name] => ...続きを読む

Aベストアンサー

普通はsql側でidでgroup by してmax(time)で最新時間を
取得します

Q関数へのポインタ渡しでの配列の初期化について

はじめまして、C言語の基本的な質問をさせてください。

C言語で、外部関数へポインタで引数を渡す場合に、
関数に渡されるのはアドレスですよね?

で、渡された関数側でそのポインタの配列の初期化を
するときにはアドレスだけの情報だと、要素数がいくつ
あるか分からず、領域の破壊をしてしまいそうな気が
するのですが?いかがでしょうか?

また、関数かなんかで、配列の要素数が分かる関数が
あったような気がするのですが、それもアドレスだけ
でわかるのでしょうか?

Aベストアンサー

疑問に思っていらっしゃる通りです。

渡された関数側では、要素数がいくつあるかわかりません。
初期化をするならば、ポインタと一緒に、要素数の情報も渡してやる必要があります。

配列の要素数がわかる関数はありません。
マクロ(プリプロセッサ)で、配列要素数を計算するのは可能ですが、
これは使用場所が限定されています。
配列を宣言したすぐ近くでないと役に立ちません。
渡された関数側では使えません。

C言語では、配列はその要素数とともに扱う必要があり、
そこをうっかりするとバグが発生する危険があります。

QMysqlの配列のデータをチェックボックスで表示させる方法を教えて下さい。

Mysqlにチェックボックスからのデータとして「0,1,3」というように
配列を登録しました。
それを今度、phpで呼び出して、ホームページ上に表示させる方法を
教えて下さい。

$labels = array("ド短期1日~OK", "週2、3日程度", "月~金曜日","土日祝日のみ", "毎日オールフリー");

データベースのテーブル名は「job」フィールド名は「working_days」です。

この配列のデータを元にチェックボックスに
<label><input type="checkbox" name="working_days[]" value="0" checked >ド短期1日~OK</label>
<label><input type="checkbox" name="working_days[]" value="1" checked >週2、3日程度</label>
<label><input type="checkbox" name="working_days[]" value="2" >月~金曜日</label>
<label><input type="checkbox" name="working_days[]" value="3" checked >土日祝日のみ</label>
<label><input type="checkbox" name="working_days[]" value="4" >毎日オールフリー</label>

というようにする方法を御指導頂けませんでしょうか。
どうぞよろしくお願い致します。

Mysqlにチェックボックスからのデータとして「0,1,3」というように
配列を登録しました。
それを今度、phpで呼び出して、ホームページ上に表示させる方法を
教えて下さい。

$labels = array("ド短期1日~OK", "週2、3日程度", "月~金曜日","土日祝日のみ", "毎日オールフリー");

データベースのテーブル名は「job」フィールド名は「working_days」です。

この配列のデータを元にチェックボックスに
<label><input type="checkbox" name="working_days[]" value="0" checked >ド短期1日~OK</label>...続きを読む

Aベストアンサー

結局 "0,1,3"で、進めているのですね・・・

まぁいろいろやり方がありますが、チェックボックスにチェックをつけるなら
以下のようなやり方がよろしいかと。


<?PHP
$str="0,1,3";
$array=split(",",$str);
foreach($array as $val){
$checked["working_days[]"][$val]=" checked";
}
$labels = array("ド短期1日~OK", "週2、3日程度", "月~金曜日","土日祝日のみ", "毎日オールフリー");
foreach($labels as $key => $val){
$html.=<<<eof
<input type="checkbox" name="working_days[]" value="{$key}" id="hoge{$key}"{$checked["working_days[]"][$key]}><label for="hoge{$key}">{$val}</label><br />\n
eof;
}
print $html;
?>

結局 "0,1,3"で、進めているのですね・・・

まぁいろいろやり方がありますが、チェックボックスにチェックをつけるなら
以下のようなやり方がよろしいかと。


<?PHP
$str="0,1,3";
$array=split(",",$str);
foreach($array as $val){
$checked["working_days[]"][$val]=" checked";
}
$labels = array("ド短期1日~OK", "週2、3日程度", "月~金曜日","土日祝日のみ", "毎日オールフリー");
foreach($labels as $key => $val){
$html.=<<<eof
<input type="checkbox" name="working_days[]" valu...続きを読む

Q関数を使った配列計算

関数を用いて配列を使った行列の演算(入力された行列の行列式、転置行列、逆行列)をするプログラムを見やすくしたいのですが、配列を関数に渡すやり方がわかりません。


出来れば実際のプログラムで教えてもらいたいです。よろしくお願いします。

Aベストアンサー

C言語の場合ですが、

void test(int a[10])
{
a[0] = 10;
}

int main(void)
{
int a[10];

test(a);
}

↑このような記述で配列を関数に渡すことが出来ます。
関数test内で書き換えた配列はmainでも反映されてます。

Qphp 2つの配列の内、片方を元にして、1つの配列にしたい

Data AとData Bをもとに
Data Cを作成したいのです。
※DataAに無くても、DataBにあるものはDataCに格納したい。

*Data A*
----------------------------
index | indexA | Name
----------------------------
1    100   A_Test1
2    101   A_Test2
3    102   A_Test3
4    103   A_Test4
5    104   A_Test5
6    105   A_Test6
7    106   A_Test7


*Data B*
----------------------------
index | indexA | flg
----------------------------
11   100   1
12   101   0
13   102   1
14   103   1
15   104   1
16   106   0


*Data C* indexAをkeyに結合
-------------------------------
index | ndexA | Name | flg
-------------------------------
1    100  A_Test1  1
2    101  A_Test2  0
3    102  A_Test3  1
4    103  A_Test4  1
5    104  A_Test5  1
6    NULL  A_Test6  0
7    106  A_Test7  0


arrayDataA = Array( [0] => Array([indexA]=> 100 [Name] = A_Test1
          [1] => Array([indexA]=> 101 [Name] = A_Test2
          [2] => Array([indexA]=> 102 [Name] = A_Test3
          [3] => Array([indexA]=> 103 [Name] = A_Test4
          [4] => Array([indexA]=> 104 [Name] = A_Test5
          [5] => Array([indexA]=> 105 [Name] = A_Test6
          [6] => Array([indexA]=> 106 [Name] = A_Test7
         ))

arrayDataB = Array( [0] => Array([indexA]=> 100 [flg] = 1
          [1] => Array([indexA]=> 101 [flg] = 0
          [2] => Array([indexA]=> 102 [flg] = 1
          [3] => Array([indexA]=> 103 [flg] = 1
          [4] => Array([indexA]=> 104 [flg] = 1
          [5] => Array([indexA]=> 106 [flg] = 1
         ))
というところまで格納するこはできたのですが
この、arrayDataAとarrayDataBを元に
arrayDataCを作成したいのです。

初歩的なことかと思いますが、
どのように、プログラムを書くと実現できるのでしょうか?

よろしくお願いいたします。

Data AとData Bをもとに
Data Cを作成したいのです。
※DataAに無くても、DataBにあるものはDataCに格納したい。

*Data A*
----------------------------
index | indexA | Name
----------------------------
1    100   A_Test1
2    101   A_Test2
3    102   A_Test3
4    103   A_Test4
5    104   A_Test5
6    105   A_Test6
7    106   A_Test7


*Data B*
----------------------------
index | indexA | flg
-------------------...続きを読む

Aベストアンサー

なんか非効率的な書き方かもしれませんが、こんな感じでどうでしょう?
これであれば$arrayDataAか$arrayDataBのどちらかに存在すれば
$arrayDataCに収めることができます

<?
$arrayDataA = Array(
'0' => Array('indexA'=> '100', 'Name' => 'A_Test1')
,'1' => Array('indexA'=> '101', 'Name' => 'A_Test2')
,'2' => Array('indexA'=> '103', 'Name' => 'A_Test4')
);

$arrayDataB = Array(
'0' => Array('indexA'=> '100', 'flg' => '1')
,'1' => Array('indexA'=> '101', 'flg' => '0')
,'2' => Array('indexA'=> '102', 'flg' => '1')
);
$arrayDataC=Array();
foreach($arrayDataA as $key=> $array){$indexAlist[$array['indexA']]['AKey']=$key;}
foreach($arrayDataB as $key=> $array){$indexAlist[$array['indexA']]['BKey']=$key;}
ksort($indexAlist);
$count=1;
foreach($indexAlist as $key=> $array){
$C=&$arrayDataC[$count++];
$C['indexA']=$key;
$C['Name']=$arrayDataA[$array['AKey']]['Name'];
$C['flg']=$arrayDataB[$array['BKey']]['flg'];
}
print "<pre>";
print_r($arrayDataC);
print "</pre>";
?>

ちなみに要件のなかに$arrayDataCは1から始まるような指定があったので
そのように対応しましたが、ふつうは配列は0からはじまります

なんか非効率的な書き方かもしれませんが、こんな感じでどうでしょう?
これであれば$arrayDataAか$arrayDataBのどちらかに存在すれば
$arrayDataCに収めることができます

<?
$arrayDataA = Array(
'0' => Array('indexA'=> '100', 'Name' => 'A_Test1')
,'1' => Array('indexA'=> '101', 'Name' => 'A_Test2')
,'2' => Array('indexA'=> '103', 'Name' => 'A_Test4')
);

$arrayDataB = Array(
'0' => Array('indexA'=> '100', 'flg' => '1')
,'1' => Array('indexA'=> '101', 'flg' => '0')
,'...続きを読む

Q配列を書き換える関数を作成してみたいのですが、

配列を書き換える関数を作成してみたいのですが、

int a[10]={3,5,7,6,7,8,10,2,3,11};

上記のような配列があるとして、
0~9のうち特定の添字を指定して、a[]の中身を書き換える関数を作る場合は、
どのような方法があるのでしょうか?

Aベストアンサー

#4 訂正
>ネストを似やすくするため全角スペースを入力しています
ネストを見やすくするため全角スペースを入力しています

どうせなので
多分間違いだとは思いますが#3さんのは
>change(a, a, 2);
change(a, 1, 2); の打ち間違いだと思われます

更に思いつき#1さんのをちょっと書き方変えてみました
>void change(int a[],int i,int n){
>a[i]=n;
>}

コール側
change(a, 1, 2);    //a[1] に2を代入する
関数側
void change(int *addr, int pt, int newdata){
  *(addr+pt) = newdata;
}

もありかな(同じくコンパイルなどはしてません)

QPHPで2次元配列を1次元配列にしたいのですが、わからないので教えてく

PHPで2次元配列を1次元配列にしたいのですが、わからないので教えてください。
例えば2次元配列を以下のようにします。
$ss[0][0]=a
$ss[0][1]=b
$ss[0][2]=c
$ss[1][0]=あ
$ss[2][0]=い
$ss[3][0]=う

これを以下のような1次元配列にしたいです。、
$ss[0][0]→$g[0],$ss[0][1]→$g[1],$ss[0][2]=$g[2]
$ss[1][0]→$h[0],$ss[2][0]→$h[1],$ss[3][0]=$h[2]


よろしくお願いします。

Aベストアンサー

for ($i=0; $i<3; $i++) {
$g[$i] = $ss[0][$i];
$h[$i] = $ss[$i+1][0];
}


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報