Applescript сравнивает элементы в одном массиве - PullRequest
0 голосов
/ 10 октября 2018

У меня есть этот список

set myList to {{1, "Bob"}, {1.5, "Jane"}, {3, "Joe"}, {1, "Jack"}}

repeat with a in myList
    --something like that a+
    if item 1 of a is equal to item 1 of a+ then
        --create list 
    end if
end repeat

Можно ли сравнить элементы по их первому свойству?Я хочу добавить в список все элементы, у которых их первый элемент совпадает

1 Ответ

0 голосов
/ 10 октября 2018

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

to filterItems from (L as list) ¬
    into |L*| as list : null ¬
    thru filter as handler
    local L, |L*|, filter

    if |L*| = null then set |L*| to {}

    script filteredItems
        property array : L
        property fn : filter
        property list : |L*|
    end script

    tell the filteredItems to repeat with x in its array
        if fn(x) = true then set ¬
            end of its list ¬
            to x's contents
    end repeat

    return the list of filteredItems
end filterItems

Эта функция (обработчик), как следует из ее названия, берет список ифильтрует его по некоторому критерию.Затем он дополнительно сохраняет отфильтрованные элементы в новом списке, который можно передать в обработчик для заполнения;или вы можете разрешить обработчику возвращать отфильтрованный список как его результат, а затем присвоить его новой переменной.

Фильтр предоставляется с помощью другого обработчика, который вы определяете.Это функция, которая воздействует на каждый элемент списка и возвращает true или false в зависимости от того, прошел ли он определенный вами тест.

В вашем конкретном случае это тест, который вам нуженПередача состоит в том, что первый элемент каждого элемента является определенным значением, например 1. Таким образом, вы получите отфильтрованный список, содержащий элементы с соответствующими первыми элементами.

Обработчик этого фильтра выглядит следующим образом:

on firstItemEquals1(x)
    item 1 of x = 1
end firstItemEquals1

Простой однострочный тест, чтобы убедиться, что первый элемент каждого элемента равен 1.

Тогда, когда вы запускаете следующую строку:

filterItems from myList thru firstItemEquals1

результат таков:

{{1, "Bob"}, {1, "Jack"}}

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

on firstItemIsOdd(x)
    (item 1 of x) mod 2 = 1
end firstItemIsOdd


on secondItemStartsWithJ(x)
    item 2 of x starts with "J"
end secondItemStartsWithJ

Затем:

filterItems from myList thru firstItemIsOdd
    --> {{1, "Bob"}, {3, "Joe"}, {1, "Jack"}}


filterItems from myList thru secondItemStartsWithJ
    --> {{1.5, "Jane"}, {3, "Joe"}, {1, "Jack"}}

РЕДАКТИРОВАТЬ: Обработка нескольких похожих случаев

* 1032Что делать, если у меня много повторяющихся первых значений?Я должен создать обработчики для каждого из них?

Нет, но нам нужно немного подкорректировать обработчик filterItems и создать другой обработчик, который работает вместе с ним, что позволит наммногократно использовать вложенные функции для выполнения трудоемких задач без необходимости создавать дополнительные обработчики для каждой задачи.

to filterItems from (L as list) ¬
    into |L*| as list : null ¬
    thru filter
    local L, |L*|, filter

    if |L*| = null then set |L*| to {}

    script itemsToBeFiltered
        property array : L
    end script
    script filteredItems
        property list : |L*|
    end script

    repeat with x in the array of itemsToBeFiltered
        tell wrapper(filter) to if fn(x) = true ¬
            then set end of filteredItems's list ¬
            to contents of x
    end repeat

    return the list of filteredItems
end filterItems

Основным изменением значимости является введение строки tell wrapper(filter).Мы вводим вспомогательную функцию для вложения наших обработчиков фильтров в объект скрипта.Функция wrapper выглядит следующим образом:

on wrapper(function)
    if function's class = script then return function

    script
        property fn : function
    end script
end wrapper

Теперь , мы можем определить обработчики фильтров, которые выглядят следующим образом:

on firstItemEquals(N)
    script
        on fn(x)
            item 1 of x = N
        end fn
    end script
end firstItemEquals

Эта новая версияОбработчик из ранее позволил нам выбрать значение, с которым сравнивать первый элемент каждого элемента в вашем списке.Таким образом, нам не нужно писать отдельные обработчики;мы можем просто сделать это:

filterItems from myList thru firstItemEquals(1)
    --> {{1, "Bob"}, {1, "Jack"}}

, а затем это:

filterItems from myList thru firstItemEquals(3)
    --> {{3, "Joe"}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...