Selecting files from collections by group size

How do I select files from a collection by the size of the group in which they reside?

Scenario: After running the dupe finder and deleting duplicate files I am left with some groups with only one member. I want to remove these groups from the collection and continue working with the remaining groups.

There doesn't seem to be a column showing the group size, so I made one:

scriptColData.value = scriptColData.item.filegroup.members.count;

It works in the file display (albeit a bit slow), but using it with Select produces errors and keeps the CPU suspiciously busy for awhile:

Select FILTERDEF script match GroupMemberCount/GroupMemberCount 1

A method was called unexpectedly (0x8000ffff)
Error at line 44, position 5

Anyone got an idea for a better approach or an improved (script) column?

Haven't had a chance to look into why that isn't working yet, but I think another way to do it would be a script that loops through the tab's files (tab.files) or groups (tab.filegroup), adding some to a Command object which then runs Select FROMSCRIPT DESELECTNOMATCH.

Or, if the aim is to remove those items from the results collection, it could run Delete REMOVECOLLECTION instead of selecting things.

Yes, removing the files with a script works much better, no delays. Select seemingly has to chew through some extra work.

The error message when running Select changed after I added a bit of error checking:

scriptColData.value = scriptColData.tab.format.group_by ? scriptColData.item.filegroup.members.count : 0;
Error at line 17, position 5
'tab.format.group_by' is null or not an object (0x800a138f)

The scripts for reference:

function OnInit(initData) {
    initData.name = 'GroupMemberCount';
    initData.version = '2024-05-07';
    initData.url = 'https://resource.dopus.com/t/selecting-files-from-collections-by-group-size/50716';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

function OnAddColumns(addColData) {
    var col = addColData.AddColumn();
    col.name = 'GroupMemberCount';
    col.method = 'OnColumn';
    col.type = 'number';
}

function OnColumn(scriptColData) {
    scriptColData.value = scriptColData.tab.format.group_by ? scriptColData.item.filegroup.members.count : 0;
}

ColumnGroupMemberCount.js.txt

function OnInit(initData) {
    initData.name = 'RemoveSinglesFromCollection';
    initData.version = '2024-05-07';
    initData.url = 'https://resource.dopus.com/t/selecting-files-from-collections-by-group-size/50716';
    initData.desc = 'RemoveSinglesFromCollection';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

function OnAddCommands(addCmdData) {
    var cmd = addCmdData.AddCommand();
    cmd.name = 'RemoveSinglesFromCollection';
    cmd.method = 'OnRemoveSinglesFromCollection';
    cmd.desc = 'RemoveSinglesFromCollection';
    cmd.label = 'RemoveSinglesFromCollection';
    cmd.template = '';
    cmd.hide = false;
    cmd.icon = 'script';
}

function OnRemoveSinglesFromCollection(scriptCmdData) {
    var cmd = scriptCmdData.func.command;
    var tab = scriptCmdData.func.sourcetab;
    var fsu = DOpus.FSUtil();

    cmd.deselect = false;

    if (String(fsu.Resolve(tab.path)).substring(0, 5) != 'coll:') return;

    cmd.ClearFiles();

    // for (var e = new Enumerator(tab.files); !e.atEnd(); e.moveNext()) {
    //     var item = e.item();
    //     if (item.filegroup.members.count > 1) continue;
    //     cmd.AddFile(item);
    // }

    for (var e = new Enumerator(tab.filegroups); !e.atEnd(); e.moveNext()) {
        var item = e.item();
        if (item.count > 1) continue;
        cmd.AddFiles(item.members);
    }

    cmd.RunCommand('Delete REMOVECOLLECTION');
}

CommandRemoveSinglesFromCollection.js.txt

1 Like

filegroup.members will cause a collection of items to be instantiated, which may take some time depending on the size of the group. But filegroup.count should be available instantly.

1 Like

Yes, filegroup.count is much faster than filegroup.members.count - nice!

However, the second problem remains: When called from Select, the column script doesn't receive a valid tab object.

Here's the new column:

function OnInit(initData) {
    initData.name = 'GroupCount';
    initData.version = '2024-05-19';
    initData.url = 'https://resource.dopus.com/t/selecting-files-from-collections-by-group-size/50716';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

function OnAddColumns(addColData) {
    var col = addColData.AddColumn();
    col.name = 'GroupCount';
    col.method = 'OnColumn';
    col.type = 'number';
}

function OnColumn(scriptColData) {
    if (!scriptColData.tab) DOpus.Output('no tab: ' + scriptColData.item);
    scriptColData.value = (scriptColData.tab && scriptColData.tab.format.group_by) ? scriptColData.item.filegroup.count : 0;
}

ColumnGroupCount.js.txt

and the Select button:

Select NONE

Select FILTERDEF script match GroupCount/GroupCount 3

// Select FILTERDEF =Val("scp:GroupCount/GroupCount")==3
XML
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>Select GroupCount</label>
	<icon1>#newcommand</icon1>
	<function type="normal">
		<instruction>Select NONE</instruction>
		<instruction />
		<instruction>Select FILTERDEF script match GroupCount/GroupCount 3</instruction>
		<instruction />
		<instruction>// Select FILTERDEF =Val(&quot;scp:GroupCount/GroupCount&quot;)==3</instruction>
	</function>
</button>

Side note: The eval form works in the filter bar :slight_smile: