Использование фильтра для объекта JSON для элементов, содержащих строку

#javascript #jquery

Вопрос:

Во-первых, я искал низко и высоко вопросы, касающиеся фильтрации объектов json по строкам, содержащим подстроки, но нашел только те, которые касаются строк, равных строкам. Я хочу отфильтровать объекты по тому, что содержит атрибут name. Поэтому, если пользователь введет строку «Smith», он вытащит второй объект(Джейн Смит). Проблема с моим кодом заключается в том, что он всегда отображает ВСЕ объекты независимо от того, что вводится во входные данные.

Вот мой код до сих пор:

 people = [
  {
    name: "John Doe",
    age: 24,
    sex: "male"
  },
  {
    name: "Jane Smith",
    age: 28,
    sex: "female"
  }
];

$('#search').on('input', function(el) {
  $('ul').empty()
  $(people).filter(function(k, person){
    return person.name.includes($(el).value)
  })

  $(people).each(function(k, person){
    $('ul').append(
      $('<li></li>').text(person.name)
    )
  })
})
 

Что я делаю не так?

Ответ №1:

filter Метод Array возвращает отфильтрованный массив.

 const regex = new RegExp( YOUR_STRING, 'gi');

const people = [
  {
    name: "John Doe",
    age: 24,
    sex: "male"
  },
  {
    name: "Jane Smith",
    age: 28,
    sex: "female"
  }
];

const rv = people.filter(
  record => record.name.match(regex)
);

console.log(rv);
 

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

1. Теперь он не показывает никаких результатов с этим jsfiddle.net/kzL8rjoa/2

2. @ShoeLace1291: Я думаю, это новый вопрос: во-первых, вы неправильно создаете новое регулярное выражение, new RegExp($(el).value, 'g') — в этом нет необходимости / , и флаги являются вторым параметром этого метода. Проверьте MDN для получения подробной информации.

Ответ №2:

В строке $('#search').on('input', function(el) { el нет селектора для jQuery, и вам нужно использовать el.target.value его для получения входных данных.

Фильтр вернет массив, поэтому, если вы работаете each с массивом filterd, вам нужно сохранить отфильтрованные данные в переменной let peopleNames = []; , иначе вы просто запустите исходный массив. также я добавил в нижний регистр (), но вам не нужно

 people = [
  {
    name: "John Doe",
    age: 24,
    sex: "male"
  },
  {
    name: "Jane Smith",
    age: 28,
    sex: "female"
  }
];
let peopleNames = [];
$('#search').on('input', function(el) {
  $('ul').empty()
  peopleNames = $(people).filter(function(k, person){
    return person.name.toLowerCase().includes(el.target.value)
  })
  $(peopleNames).each(function(k, person){
    $('ul').append(
      $('<li></li>').text(person.name)
    )
  })
}) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="search" />
<ul></ul> 

Ответ №3:

Функция jQuery .filter() возвращает новый объект jQuery с примененным фильтром. Итак, вы должны вызвать .each() для этого нового объекта, вместо того, чтобы вызывать его $(people) снова.

Кроме того, $(el).value должно быть $(el.target).val()) , так el как это объект события jQuery, а не элемент DOM.

 people = [
  {
    name: "John Doe",
    age: 24,
    sex: "male"
  },
  {
    name: "Jane Smith",
    age: 28,
    sex: "female"
  }
];

$('#search').on('input', function(el) {
  $('ul').empty()
  $(people).filter(function(k, person){
    return person.name.includes($(el.target).val())
  }).each(function(k, person){
    $('ul').append(
      $('<li></li>').text(person.name)
    )
  })
})
 

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

1. Хм, теперь, похоже, он не показывает никаких результатов jsfiddle.net/kzL8rjoa/1

2. Я отредактировал ответ. Я забыл, что изменил ваш код для тестирования!