Как проверить, существует ли пара значений ключа (в массиве) в другом массиве? - PullRequest
2 голосов
/ 08 мая 2020

У меня есть два массива, например:

invoices: [
    {id: 90, Client: 'Bob', paid: false, total: 900},
    {id: 91, Client: 'Sarah', paid: false, total: 400}
]

и:

result: [{km: 200, hours: 20, Person: 'Sarah'}]

Массив invoices является ответом JSON от GET и иногда будет больше чем result, поэтому в данном случае invoices имеет Боба, а его нет в result.

Как я могу получить id любых объектов, чей Client не отображается как Person дюйм result? Я пробовал сделать это двойным for l oop, но не совсем получилось.

Ответы [ 4 ]

1 голос
/ 08 мая 2020

Создавая объект с ключами, которые являются значениями Person из result, мы можем использовать это для эффективной фильтрации значений в invoices, а затем использовать map для возврата только id значений отфильтрованных результат:

const invoices =  [
    {id: 90, Client: 'Bob', paid: false, total: 900},
    {id: 91, Client: 'Sarah', paid: false, total: 400}
]

const result =  [{km: 200, hours: 20, Person: 'Sarah'}]

const resindexes = result.reduce((c, o, i) =>
  (c[o.Person] = i, c), {});

ids = invoices.filter(o => resindexes[o.Client] === undefined).map(o => o.id);

console.log(ids);
1 голос
/ 08 мая 2020

Вы можете отфильтровать массив invoices, используя массив result в качестве этого аргумента, и проверить наличие Client в нем ( см. MDN для Array.filter). Обратите внимание, что filter -callback должен быть обычной функцией (т.е. не стрелочной функцией), чтобы можно было использовать массив результатов для thisArg.

console.log( `Id(s) not in result\n`, 
  [ {id: 90, Client: 'Bob', paid: false, total: 900}, 
    {id: 91, Client: 'Sarah', paid: false, total: 400},
    {id: 92, Client: 'Mia', paid: false, total: 200} ]
  .filter( 
    function(v) { return !this.find(n => n.Person === v.Client); }, 
    [{km: 200, hours: 20, Person: 'Sarah'}] // <= thisArg
   )
   .map(v => v.id) // <= fetch the found id's
   .join()
);
.as-console-wrapper { top: 0; max-height: 100% !important; }
0 голосов
/ 08 мая 2020

Или вы можете сделать это, сделав карту людей.

Плюс к этому, у вас есть доступ к данным о людях по имени клиента.

Обратите внимание, что я увеличил счета для 1 строки для лучшего просмотра результатов.

// Data enter code here
const invoices = [
    {id: 90, Client: 'Bob', paid: false, total: 900},
    {id: 91, Client: 'Sarah', paid: false, total: 400},
    {id: 92, Client: 'Joe', paid: false, total: 400}
];
const personsArr = [{km: 200, hours: 20, Person: 'Sarah'}];

// Query
const persons = new Map(
    personsArr.map(r =>{ 
        return [r.Person, r]
    }
  )
);
// invoices which do not have results
const orphans = invoices.filter((i)=>!persons.has(i.Client));
// id of invoices which do not have results
const orphansId = orphans.map((o)=>o.id)

console.log(orphansId);

возвращает: [90, 92]

0 голосов
/ 08 мая 2020

Использование Set и flatMap дает выразительное и эффективное решение. Set потребляет массив и позволяет вам проверять элементы в постоянное время. По сути, flatMap позволяет фильтровать и отображать одновременно.

// Data
const invoices = [
  {id: 90, Client: 'Bob', paid: false, total: 900},
  {id: 91, Client: 'Sarah', paid: false, total: 400}
];
const personsArr = [{km: 200, hours: 20, Person: 'Sarah'}];

// Query
const persons = new Set(personsArr.map(r => r.Person));
const result = invoices.flatMap(i => !persons.has(i.Client) ? i.id : []);
console.log(result);
...