リスト内の同じ名前の項目を識別するリスト内で重複している項目を識別するための巧妙な方法があるかどうか知りたいです。私のリストは次のようになります。
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
リスト内の「Per」の位置をすべて返します。つまり
[3, 4, 5, 6, 7]
リストをループして答えを得ることができます。しかし、ループを回避する別の方法はありますか?
自動化とスクリプトRe: リスト内の同じ名前の項目を識別するピーター、
もっと良い方法があるかもしれない。
(正しい解決策については、Stan の回答を参照してください。)
しかし、長い一日の終わりに私が作成した解決策がこれです。これは、値マトリックスを取得し、重複する値を持つ値マトリックス内の各値のエントリと、キーに対して見つかったすべての位置を含む連想配列を作成します。
Names Default To Here( 1 );
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
dt = New Table( "test", private, New Column( "val", character ) );
dt:val << set values( values );
array = Associative Array( values );
uniqs = array << get keys;
For Each( {vals}, uniqs,
positions = dt << get rows where( :val == vals );
If( Length( positions ) > 1,
array << insert item( vals, positions ),
array << remove item( vals )
);
);
Close( dt, nosave );
Re: リスト内の同じ名前の項目を識別するこんにちは@pmroz
Loc関数を使うこともできます。
loc(値、「Per」);
乾杯、
スタン
//:*/
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
loc(値、"Per")
/*:
[3、4、5、6、7]
Re: リスト内の同じ名前の項目を識別する完全一致のみが必要な場合は、JM18より前ではLocとJMP18のWhere()を使用できました。
Names Default To Here(1);
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
idx1 = Loc(values, "Per"); // Before JMP17
idx2 = Where(values == "Per"); // JMP18
show(idx1, idx2);
また、JMP18で完全一致でない一致が必要な場合でも、Where()でそれが可能です。
Names Default To Here(1);
values = {"APerBC", "PerDEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
idx2 = Where(Contains(values, "Per")); // JMP18
show(idx2);Re: リスト内の同じ名前の項目を識別するloc() は数値にしか機能しないと思っていました。ああ! 素晴らしい解決策です。
皆さんありがとう!
-ピーター
Re: リスト内の同じ名前の項目を識別するスタン、素晴らしい解決策ですね。あなたの解決策を私のコードに組み込んで、すべての重複値をチェックしてみました。
Names Default To Here( 1 );
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
array = Associative Array( values );
uniqs = array << get keys;
For Each( {vals}, uniqs,
positions = loc(values, vals);
If( Length( positions ) > 1,
array << insert item( vals, positions ),
array << remove item( vals )
);
);Re: リスト内の同じ名前の項目を識別するループを一切書かずに済む解決策をご紹介します。この方法は、あなたの例だけでなく、コード内で重複する値を特定することなく、複数の重複値に対しても機能します。
names default to here(1);
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
// make data table with values //
dt = new table("item table" /*, private*/);
dt << new column("Items", character, nominal, set values(values));
// identify the duplicate rows //
dt << Select duplicate rows( Match( :Items ) );
// if you also want the first of the duplicate values, otherwise skip the next two lines //
dt << Go To( :Items );
dt << Select All Matching Cells();
// save the selected row results //
dupLocations = dt << get selected rows();
// clean up the data table //
close(dt, no save);
show(dupLocations);