The kind of pattern you are trying is often the right one, but bamboozled here because the Contacts
records don't have single-string email values.
(Instead each person record includes a (possibly empty) list of email strings).
One approach might look something like this:
(() => {
"use strict";
// main :: IO ()
const main = () => {
const
appContacts = Application("Contacts"),
people = appContacts.people,
names = people.name(),
// Each person record has a (possibly empty)
// *list* of email addresses.
emailLists = people.emails.value(),
namesWithEmails = [].concat(
...zipWith(
name => emailList => 0 < emailList.length ? [{
name,
emailList
}] : []
)(names)(emailLists)
);
return namesWithEmails.flatMap(
record => record.emailList.includes(
"email.email.com"
) ? (
[record]
) : []
);
};
// --------------------- GENERIC ---------------------
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
// A list constructed by zipping with a
// custom function, rather than with the
// default tuple constructor.
xs => ys => xs.map(
(x, i) => f(x)(ys[i])
).slice(
0, Math.min(xs.length, ys.length)
);
// MAIN ---
return main();
})();