Identificar elementos con el mismo nombre en una listaMe pregunto si existe una manera ingeniosa de identificar elementos en una lista que sean duplicados entre sí. Mi lista se ve así:
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
Quiero devolver todas las posiciones de "Por" en la lista. Es decir
[3, 4, 5, 6, 7]
Puedo recorrer la lista para obtener la respuesta. ¿Pero hay otra forma de evitar el bucle?
Automatización y secuencias de comandosRe: Identificar elementos del mismo nombre en una listaPedro,
Podría haber una mejor manera de hacer esto,
(Consulte la respuesta de Stan para conocer la solución correcta).
pero aquí está mi solución creada al final de un largo día. Toma su matriz de Valores y crea una matriz asociativa con una entrada para cada valor en la matriz de Valores que tiene valores duplicados y todas las posiciones encontradas para la clave.
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: Identificar elementos del mismo nombre en una listaHola @pmroz
Podrías usar la función Loc .
loc(valores, "Por");
salud,
estan
//:*/
valores = {"ABC", "DEF", "Por", "Por", "Por", "Por", "Por", "XYZ", "UVW"};
loc(valores, "Por")
/*:
[3, 4, 5, 6, 7]
Re: Identificar elementos del mismo nombre en una listaSi solo desea coincidencias exactas, antes de JM18 podía usar Loc y en 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);
Además, si necesita incluso coincidencias no exactas en JMP18, Where() puede hacerlo
Names Default To Here(1);
values = {"APerBC", "PerDEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
idx2 = Where(Contains(values, "Per")); // JMP18
show(idx2);Re: Identificar elementos del mismo nombre en una listaPensé que loc() solo funcionaba con números. DOH! Grandes soluciones.
¡Gracias a todos!
-Pedro
Re: Identificar elementos con el mismo nombre en una listaBuena solución, Stan. Aquí tienes tu solución incorporada a mi código, que comprueba todos los valores repetidos.
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: Identificar elementos con el mismo nombre en una listaAquí tienes una solución que no requiere bucles. Este método funciona en tu ejemplo y también con varios valores duplicados sin necesidad de identificarlos en el código.
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);