Как мне получить (людей, чей идентификатор адресов содержит AddressID) в JXA?

#macos #javascript-automation

#macos #javascript-автоматизация

Вопрос:

Я использую JavaScript с osascript в macOS Mojave 10.14.3, чтобы написать скрипт, который отображает людей и их контактную информацию из контактов. Я добавляю функцию для отображения всех людей в определенном городе. Вот упрощенная версия, которая выполняется в редакторе сценариев:

 contacts = Application('Contacts').people;
matchingAddresses = contacts.addresses.whose({city: "San Diego"});

var addressIds = [];
for (var matchedAddress of matchingAddresses()) {
    if (matchedAddress.length > 0) {
        addressIds.push(matchedAddress[0].id());
    }
}

//loop contacts and get those with a matching address
var personIds = [];
for (var possiblePerson of contacts()) {
    for (var addressToCheck of possiblePerson.addresses()) {
        if (addressIds.includes(addressToCheck.id())) {
            var personId = possiblePerson.id();
            if (!personIds.includes(personId)) {
                personIds.push(personId);
            }
        }
    }
}

personIds.length;
  

У меня есть тестовая версия AppleScript, которая немного более эффективна. Вместо того, чтобы перебирать все контакты, он перебирает соответствующие адреса и получает people whose id of addresses contains addressId :

 tell application "Contacts"
    set matchingAddresses to (every address where its city is "San Diego") of every person

    set personIds to {}
    repeat with matchedAddressList in matchingAddresses
        repeat with possibleAddress in items of contents of matchedAddressList
            set addressId to id of possibleAddress
            set matchingPerson to first item of (people whose id of addresses contains addressId)
            if not (personIds contains id of matchingPerson) then
                set end of personIds to id of matchingPerson
            end if
        end repeat
    end repeat

    count of personIds
end tell
  

AppleScript (people whose id of addresses contains addressId) всегда возвращает одного пользователя, потому что идентификаторы адресов уникальны, и поэтому список адресов только одного пользователя может содержать какой-либо конкретный идентификатор адреса.

Если в JavaScript или AppleScript есть лучшие способы получать людей из контактов по городу одного из их адресов, меня бы это заинтересовало.

Но мой вопрос в том, есть ли способ дублировать функциональность first item of (people whose id of addresses contains addressId) с помощью JavaScript, чтобы получить одного человека, у которого есть адрес, соответствующий этому идентификатору адреса?

Ответ №1:

Может быть, что-то более похожее…

 const contacts = Application('Contacts').people,
    matchingAddresses = contacts.addresses.whose({city: "San Diego"}),
    addressIds = matchingAddresses().filter(a=>a.length).map(a=>a[0].id());

addressIds[0]; // the first id
  

Или, если вам нужен адрес…

 const contacts = Application('Contacts').people,
    address = contacts.addresses.whose({city: "San Diego"})().filter(a=>a.length)[0]

address
  

Комментарии:

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

2. Запятая продолжает объявление const . Я объявил 3 константы. Const похож на var, но после назначения он никогда не может быть изменен. Это не разделитель строк. Замена запятых на точки с запятой превращает 2-й и 3-й в необъявленные переменные. Это нехорошо. Но это все еще работает. Программисты JXA намного более небрежны в объявлении. Я много лет изучал JavaScript, я предпочитаю объявлять var или const .