Javascript array.filter по элементам в дочерних элементах

У меня есть массив таких объектов (клиентов):

"{"client_id":"AAA1","contracts":[{"contract_id":"CON1-AAA1","revisions":[{"date":"2018-07-30","status":"First Sign"}]}]}"

Я могу без проблем фильтровать по client_id:

var query = clients.filter(x => x.client_id == "AAA1");

Однако я хотел бы выполнить фильтрацию по дате или статусу ревизии, я тестировал следующие действия, но получаю сообщение об ошибке «Uncaught TypeError: Cannot read property 'status' of undefined»

var query = clients.filter(x => x.contracts.revisions.status == "First Sign");

Возможно ли это сделать так или это бред? :)

"{"client_id":"AAA1","contracts":[{"contract_id":"CON1-AAA1"‌​,"revisions":[{"date‌​":"2018-07-30","stat‌​us":"First Sign"}]}]}" - это не массив. Это строка. Пожалуйста, предоставьте минимальный воспроизводимый пример, используя кнопку <>
mplungjan 30.07.2018 10:18

@korocota, пожалуйста, предоставьте правильный JSON, если это так!

Prashant Pimpale 30.07.2018 10:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
4 637
4

Ответы 4

Это происходит, поскольку ревизии и контракты представляют собой массив.

Вам нужно будет выбрать между любым предметом, равным всем предметам, равным.

Использование Array.prototype.some - любой элемент в массиве отвечает критерию. Использование Array.prototype.every - все элементы в массиве соответствуют критериям.

Пример поиска клиента, у которого есть контракт хотя бы на пересмотр со статусом «Первый знак»:

const query = clients.filter(x => x.contracts.some(c => c.revisions.some(r => r.status == "First Sign")));
contracts - тоже массив
barbsan 30.07.2018 10:20
x.contracts.revisions Но revisions не является свойством contracts, contracts - это массив
CertainPerformance 30.07.2018 10:20

Ага, не заметил этого. Я исправил свой ответ.

Amir Popovich 30.07.2018 10:22

Клиент - это объект с идентификатором и массивом контрактов, каждый контракт имеет идентификатор с массивом ревизий, каждая ревизия имеет дату и статус, если это имеет смысл

korocota 30.07.2018 10:22

Вы можете добиться этого, используя комбинацию Array#filter и двух Array#some:

const clients = [{
  "client_id": "AAA1",
  "contracts": [{
    "contract_id": "CON1-AAA1",
    "revisions": [{
      "date": "2018-07-30",
      "status": "First Sign"
    }]
  }]
}, {
  "client_id": "AAA2",
  "contracts": [{
    "contract_id": "CON1-AAA2",
    "revisions": [{
      "date": "2018-08-30",
      "status": "Second Sign"
    }]
  }]
}];

let result = clients.filter(cl => cl.contracts.some(c => c.revisions.some(r => r.status == 'First Sign')));
console.info(result);

OP, вероятно, хочет фильтровать clients, а не contracts

Adelin 30.07.2018 10:22

@Adelin Отредактировано ^^

Zenoo 30.07.2018 10:28

@korocota ну, он не может принять голос, если вы его не дадите :) текущий +1 от меня :)

Adelin 30.07.2018 10:31

Используйте filter и some, как показано ниже:

var clients = [
{
    "client_id": "AAA1",
    "contracts": [
    {
        "contract_id": "CON1-AAA1",
        "revisions": [
        {
            "date": "2018-07-30",
            "status": "First Sign"
        }]
    }]
},
{
    "client_id": "AAA1",
    "contracts": [
    {
        "contract_id": "CON1-AAA1",
        "revisions": [
        {
            "date": "2018-07-30",
            "status": "Second Sign"
        }]
    }]
}]

var query = clients.filter(
    x => x.contracts.some(y => y.revisions.some(z => z.status == "First Sign")));

console.info(query);

Итак, поскольку ваше сообщение об ошибке и описание проблемы четко указывают, что то, что вы опубликовали в виде строки (которая выглядит как объект), действительно является выдержкой из большего массива, вы можете сделать следующее

const arr = [{"client_id":"AAA1","contracts":[{"contract_id":"CON1-AAA1","revisions":[{"date":"2018-07-30","status":"First Sign"}]}]}];
const res = arr.filter(client => client.contracts.some(contract => contract.revisions.some(revision => revision.status === 'First Sign')));

console.info(res);

Другие вопросы по теме