Фильтрация записей путем передачи запроса в функцию из массива - PullRequest
0 голосов
/ 10 июля 2019

Я хочу получать записи, передавая аргументы запроса в функцию в JavaScript.

const data = [{
    name: "ab",
    class: 1,
    grade: "A",
    teacher: {
      teacherName: "tab",
      age: 34,
      school: "ab pblc scl"
    }
  },
  {
    name: "cd",
    class: 2,
    grade: "B",
    teacher: {
      teacherName: "efg",
      age: 35,
      school: "cd pblc scl"
    }
  }
]

Аргументы моей функции фильтра (1-й аргумент - массив, а 2-й - запрос, который может быть любым)

Это некоторые условия теста.

filterMe(data,{name : "cd", class:"2",teacherName:"efg"}) должен вернуть весь объект

{
   name: "cd",
   class: 2,
   grade: "B",
   teacher: {
      teacherName: "efg",
      age: 35,
      school: "cd pblc scl"
   }
}

любая помощь будет высоко оценена.

Ответы [ 2 ]

2 голосов
/ 10 июля 2019

Вы можете использовать Object.entries, чтобы получить каждый ключ от предоставленного объекта, и проверить, совпадает ли каждая пара с условием фильтра, используя every. Если значение является объектом, рекурсивно вызовите функцию:

const data = [{
    name: "ab",
    class: 1,
    grade: "A",
    teacher: {
      teacherName: "tab",
      age: 34,
      school: "ab pblc scl"
    }
  },
  {
    name: "cd",
    class: 2,
    grade: "B",
    teacher: {
      teacherName: "efg",
      age: 35,
      school: "cd pblc scl"
    }
  }
]

const advFilter = (d, f) => d.filter(o => nestedEvery(o, f))
const nestedEvery = (o, v) => Object.entries(v).every(([k,v]) => typeof v === 'object' ? nestedEvery(o[k], v) : o[k] === v)

const log = console.log
log(advFilter(data, { name: "cd", class: 2, teacher: { teacherName: 'efg' } })) // returns cd
log(advFilter(data, { name: "cd", class: 2, teacherName: 'efg' })) // returns []
log(advFilter(data, { name: "ab", class: 1, teacher: { teacherName: 'tab' } })) // returns ab

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

0 голосов
/ 10 июля 2019

Я тестировал некоторые тестовые случаи, думаю, мой код работает. Попробуйте:

const data = [{
    name: "ab",
    class: 1,
    grade: "A",
    teacher: {
      teacherName: "tab",
      age: 34,
      school: "ab pblc scl"
    }
  },
  {
    name: "cd",
    class: 2,
    grade: "B",
    teacher: {
      teacherName: "efg",
      age: 35,
      school: "cd pblc scl"
    }
  }
]

function filterMe(data, query){
  result = data.filter( x => {
    return Object.keys(x).some( y => {
        
        if(y === "teacher"){
          return Object.keys(x[y]).some( u => {
            return Object.keys(query).some( q => {
                return query[q] === x[y][u]
            })
          })
        }else{
           return Object.keys(query).some( q => {
                return query[q] === x[y]
            })
        }
      })
    })

  console.log(result);
}

filterMe(data,{name : "cd", class:"2",teacherName:"efg"})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...