Фильтровать записи в AppleScript - PullRequest
0 голосов
/ 15 ноября 2018

Попытка получить определенные записи на основе значения свойства:

set x to {{a:1, b:2, c:"yes"}, {a:2, b:2, c:""}, {a:3, b:2, c:"no"}}
get every item of x whose (c ≠ "")

дает

error "The variable c is not defined." number -2753 from "c"

Что я делаю не так?

Этот цикл работает:

set y to {}
repeat with i in x
    if i's c ≠ "" then
        set end of y to i
    end if
end repeat
get y

... дает:

{item 1 of {{a:1, b:2, c:"yes"}, {a:2, b:2, c:""}, {a:3, b:2, c:"no"}}, item 3 of {{a:1, b:2, c:"yes"}, {a:2, b:2, c:""}, {a:3, b:2, c:"no"}}}

... но кажется излишним, и похоже, что это указатели на оригинальную запись?

1 Ответ

0 голосов
/ 15 ноября 2018

Записи AppleScript не могут быть отфильтрованы так, как вы надеялись, поэтому с простым AppleScript вы абсолютно правы как в подходе, использующем цикл повторения, так и в наблюдении, что он возвращает ссылки на значения, а не сами значения.

Чтобы разыменовать их, измените вашу последнюю строку на

get y's contents

или

get the contents of y 

Если вы не возражаете добавить немного Objective-C в ваш скрипт, мы можем создать объект сценария , который определяет реализацию обработчика filterItems, который вы можете использовать для фильтрации списков через строка предиката , которая на самом деле дает вам гораздо больше власти над тем, как вещи и какие вещи фильтруются:

script array
    use framework "Foundation"

    property this : a reference to current application
    property NSArray : a reference to NSArray of this
    property NSPredicate : a reference to NSPredicate of this


    to filterItems for x as string given list:L
        local L, x

        NSPredicate's predicateWithFormat:x
        (NSArray's arrayWithArray:L)'s ¬
            filteredArrayUsingPredicate:result
        result as anything
    end filterItems
end script

Вы можете добавить это в конец вашего скрипта, чтобы не мешать ему, а затем использовать его для фильтрации списка записей, например:

set x to {{a:1, b:2, c:"yes"}, {a:2, b:2, c:""}, {a:3, b:2, c:"no"}}

filterItems of array for "c!=''" given list:x
    --> {{a:1, b:2, c:"yes"}, {a:3, b:2, c:"no"}}

Обратите внимание, однако, что существуют различия в способах сравнения Objective-C и AppleScript. Например, если мы объявим x как:

set x to {{a:1, b:2}, {a:2, b:2, c:""}, {a:3, b:2, c:"no"}}

любой гипотетический фильтр AppleScript, предписанный для предиката c, не являющегося пустой строкой, выдаст ошибку, как только натолкнется на объект (элемент 1 из x: {a:1, b:2}), который не содержит свойства c. Objective-C немного более инклюзивен в своей оценке:

filterItems of array for "c!=''" given list:x
    --> {{a:1, b:2}, {a:3, b:2, c:"no"}}

Если вы были удивлены включением {a:1, b:2} в этот результат, вы захотите предсказать фильтр для двух условий, а именно, что возвращаемые объекты содержат свойство с именем c, и что это свойство не является пустая строка:

filterItems of array for "SELF CONTAINS c && c!=''" given list:x
    --> {a:3, b:2, c:"no"}

Обратите внимание, что, поскольку в результате получается один объект, в отличие от AppleScript, Objective-C обойдется без формальности возврата одного элемента list и вернет сам объект, который является record.

Дополнительную информацию о строках предикатов и о том, как их формулировать, можно найти в разделе Краткий обзор , где приведено краткое изложение общего синтаксиса и всего, начиная с Основные сравнения до конца этой страницы для различных операторов, которые могут использоваться для различных типов значений.

Однако, если вам нужна дополнительная помощь в формировании строки предиката для удовлетворения конкретных случаев, оставьте комментарий, и я постараюсь вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...