Identificare gli elementi con lo stesso nome in un elencoMi chiedo se esiste un modo intelligente per identificare gli elementi in un elenco che sono duplicati l'uno dell'altro. La mia lista è simile a questa:
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
Voglio restituire tutte le posizioni di "Per" nell'elenco. Cioè
[3, 4, 5, 6, 7]
Posso scorrere l'elenco per ottenere la risposta. Ma esiste un altro modo per evitare il loop?
Automazione e scriptingRi: Identificare gli elementi con lo stesso nome in un elencoPeter,
Potrebbe esserci un modo migliore per farlo,
(Vedi la risposta di Stan per la soluzione corretta.)
ma ecco la mia soluzione creata alla fine di una lunga giornata. Prende la matrice dei valori e crea un array associativo con una voce per ciascun valore nella matrice dei valori che ha valori duplicati e tutte le posizioni trovate per la chiave.
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 );
Ri: Identificare gli elementi con lo stesso nome in un elencoCiao @pmroz
Potresti usare la funzione Loc --
loc(valori, "Per" );
saluti,
Stan
//:*/
valori = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
loc(valori, "Per")
/*:
[3, 4, 5, 6, 7]
Ri: Identificare gli elementi con lo stesso nome in un elencoSe desideri solo corrispondenze esatte, prima di JM18 potresti utilizzare Loc e in 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);
Inoltre, se hai bisogno di corrispondenze anche non esatte in JMP18, Where() è in grado di farlo
Names Default To Here(1);
values = {"APerBC", "PerDEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
idx2 = Where(Contains(values, "Per")); // JMP18
show(idx2);Ri: Identificare gli elementi con lo stesso nome in un elencoPensavo che loc() funzionasse solo sui numeri. DOH! Ottime soluzioni.
Ringrazia tutti!
-Peter
Re: Identificare gli elementi con lo stesso nome in un elencoOttima soluzione, Stan. Ecco la tua soluzione integrata nel mio codice che controlla tutti i valori ripetuti.
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: Identificare gli elementi con lo stesso nome in un elencoEcco una soluzione che non richiede la scrittura di cicli. Questo metodo funziona nel tuo esempio e funziona anche con valori duplicati multipli, senza dover identificare i valori duplicati nel codice.
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);