识别列表中的同名项目我想知道是否有一种巧妙的方法来识别列表中彼此重复的项目。我的列表如下所示:
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
我想返回列表中“Per”的所有位置。即
[3, 4, 5, 6, 7]
我可以循环遍历列表来获取答案。但是还有其他方法可以避免循环吗?
自动化和脚本回复:识别列表中的同名项目彼得,
可能有更好的方法可以做到这一点,
(请参阅 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 );
回复:识别列表中的同名项目嗨@pmroz
你可以使用Loc 函数——
loc(值,“每”);
干杯,
斯坦
//:*/
值 = {“ABC”、“DEF”、“Per”、“Per”、“Per”、“Per”、“Per”、“XYZ”、“UVW”};
loc(值,"每")
/*:
[3, 4, 5, 6, 7]
回复:识别列表中的同名项目如果你只想要精确匹配,在 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);回复:识别列表中的同名项目我以为 loc() 只适用于数字。哎呀!很棒的解决方案。
谢谢大家!
-彼得
回复:识别列表中的同名项目斯坦,好主意。这是你整合到我的代码里的解决方案,用来检查所有重复值。
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 )
);
);回复:识别列表中的同名项目这是一个不需要编写任何循环的解决方案。此方法适用于您的示例,并且也适用于多个重复值,而无需在代码中识别重复值。
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);