- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Identify Same-Name Items in a List
I'm wondering if there's a slick way to identify items in a list that are duplicates of each other. My list looks like this:
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
I want to return all of the positions of "Per" in the list. I.e.
[3, 4, 5, 6, 7]
I can loop over the list to get the answer. But is there another way that avoids the loop?
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
Hi @pmroz
You could use the Loc function--
loc(values, "Per" );
cheers,
Stan
//:*/
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
loc(values, "Per")
/*:
[3, 4, 5, 6, 7]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
Peter,
There might be a better way to do this,
(See Stan's response for the correct solution.)
but here is my solution created at the end of a long day. It takes your Values matrix and creates an Associative array with an entry for each value in the Values matrix that has duplicate values and all of the positions found for the key.
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 );
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
Hi @pmroz
You could use the Loc function--
loc(values, "Per" );
cheers,
Stan
//:*/
values = {"ABC", "DEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
loc(values, "Per")
/*:
[3, 4, 5, 6, 7]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
Good solution Stan. Here is your solution incorporated into my code which checks for all repeating values.
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 )
);
);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
If you want only exact matches, before JM18 you could use Loc and 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);
Also if you need even non-exact matches in JMP18, Where() is able to do that
Names Default To Here(1);
values = {"APerBC", "PerDEF", "Per", "Per", "Per", "Per", "Per", "XYZ", "UVW"};
idx2 = Where(Contains(values, "Per")); // JMP18
show(idx2);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
Here is a solution that doesn't require writing any loops. This method works on your example, and also works on multiple, duplicate values without having to identify the duplicate values in the code.
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: Identify Same-Name Items in a List
I thought loc() only worked on numbers. DOH! Great solutions.
Thanks all!
-Peter