Javascript - поиск строки в массиве объектов

Я хотел бы найти строку в массиве объектов и вернуть соответствующие объекты. Пытаюсь использовать здесь es6.

Пожалуйста, найдите код ниже:

// set of keys
const defConfigs = [{
    title: "Id",
    key: "id"
  },
  {
    title: "Tenant",
    key: "tenant"
  },
  {
    title: "Opened",
    key: "opened"
  },
  {
    title: "Title",
    key: "title"
  },
  {
    title: "Status",
    key: "status"
  },
  {
    title: "Priority",
    key: "priority"
  }
];

// items as array of objects
const items = [{
    id: "INC000000004519",
    title: "Follow-up after INC000000004507",
    description: null,
    urgency: "4-Low",
    severity: "4-Minor/Localized"
  },
  {
    id: "INC000000004515",
    title: "network drop:↵Network Element CVU042_Johnstown get unsynchronized↵Network Element CVU043_Redman",
    description: "Client network drop since 08:51 until 09:06, pleas…ork Element CVU045_North_Salem get unsynchronized",
    urgency: "3-Medium",
    severity: "3-Moderate/Limited"
  },
  {
    id: "INC000000004088",
    title: "not able to schedule GPEH in ABC",
    description: "Contact: [email protected]↵+14692669295↵…WCDMA, we are not able to schedule GPEH in ABC. I",
    urgency: "4-Low",
    severity: "4-Minor/Localized"
  },
  {
    id: "INC000000004512",
    title: "SR Updated - P3 - 2018-0427-0305 - xyz TELECOMMUNICATIONS ROMANIA S.R.L - Lost the  mng connect",
    description: null,
    urgency: "4-Low",
    severity: "4-Minor/Localized"
  },
  {
    id: "INC000000004414",
    title: "Acme incident 1 title",
    description: "Acme incident 1 description",
    urgency: "2-High",
    severity: "1-Extensive/Widespread"
  }
];


// trying to search for string in keys defined in defConfigs
items.filter(item =>
  defConfigs.forEach((def) => {
    if (def.key in item) {
      return (item[def.key].toString().toLowerCase().match('low').length > 1);
    }
  }));

// always throws an error Uncaught TypeError: Cannot read property 'length' of null
console.info(items);

Здесь есть 3 объекта со строкой «low», и я ожидаю, что код вернет первый элемент (где «title» - «Folнизкий-up after»); но match никогда не возвращается.

Как мне найти строку в массиве объектов и вернуть эти объекты в результате?

.match('low').length выдает ошибку, если совпадение не найдено. Также обратите внимание, что def.key in item неверен для всех ваших примеров.
Jared Smith 13.05.2018 20:04

Вы можете использовать цикл foreach и преобразовать каждый объект в массив. Сделайте регулярное выражение match str.match('low'). Если он вернет истину, верните этот элемент

Nicholas Porter 13.05.2018 20:05

Разве он не должен возвращать предмет один? Два пункта содержат низкую, но срочную категорию.

Salman A 13.05.2018 20:58

Да, точно. «низкий» относится к категории срочности, которой нет в defConfig. Но в одном из объектов title есть строка low.

Valay 13.05.2018 21:06
Поведение ключевого слова "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) для оценки ваших знаний,...
2
4
126
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Функция String.prototype.match() вернет null, если совпадений нет, поэтому вам нужно проверить этот случай. Затем вы можете использовать функцию Array.prototype.some(), чтобы убедиться, что хотя бы один элемент в массиве соответствует вашему условию. Например:

items.filter(item =>
  // check if at least one key from `defConfigs` on `item` matches 'low'
  defConfigs.some((def) => {
    if (def.key in item) {
      const matched = item[def.key].toString().toLowerCase().match('low')
      // return true if item matched
      return !!matched
   }
   // match not found by default
   return false
}));

String.prototype.match () вернет null, если совпадение не найдено. Вы должны строго сравнивать результат совпадения с нулевым, если хотите, чтобы он работал.

Вам стоит взглянуть на Array.prototype.filter. Он возвращает новый массив и не изменяет ссылку, переданную в качестве аргумента, ваши исходные элементы в безопасности (на данный момент).

Слово «низкий» встречается только в атрибуте острая необходимость, а в вашем массиве defConfigs этого поля нет. Поэтому после добавления его в массив выполните следующие действия:

let newItems=items.filter(item => {


    let count= defConfigs.reduce((acc, def) => {

        if (def.key in item) {
            let arr = item[def.key].toString().toLowerCase().match(/low/gi)
            return acc + (arr ? 1 : 0);
        }
        else {

            return acc;
        }
    }, 0)

    return count >0
});

console.info(newItems);
  • Итак, сначала определите новую переменную для отфильтрованных данных новые предметы
  • Затем я использовал функцию уменьшать, чтобы узнать, есть ли совпадение во всем объекте
  • в последнюю очередь использовал регулярное выражение / low / gi в функции сопоставления

Верный. Пытался изменить код, но SO не позволяет.

Valay 13.05.2018 20:51

если мое решение помогло вам решить проблему, отметьте его как решенное

Ahmed Abdelaal 13.05.2018 21:05

'low' относится к категории срочности, которой нет в defConfig. Но в заголовке одного из объектов есть строка low.

Valay 13.05.2018 21:07

В вашем операторе if, if (def.key in item), он проверит, совпадает ли значение def.key с именем атрибута в элементе. Чтобы осуществить то, о чем вы думали, просмотрите комментарии в приведенном ниже коде:

// set of keys
const defConfigs = [{title: "Id", key: "id"},
{title: "Tenant", key: "tenant"},
{title: "Opened", key: "opened"},
{title: "Title", key: "title"},
{title: "Status", key: "status"},
{title: "Priority", key: "priority"}];

// items as array of objects
const items = [{id: "INC000000004519", title: "Follow-up after INC000000004507", description: null, urgency: "4-Low", severity: "4-Minor/Localized"},
{id: "INC000000004515", title: "network drop:↵Network Element CVU042_Johnstown get unsynchronized↵Network Element CVU043_Redman", description: "Client network drop since 08:51 until 09:06, pleas…ork Element CVU045_North_Salem get unsynchronized", urgency: "3-Medium", severity: "3-Moderate/Limited"},
{id: "INC000000004088", title: "not able to schedule GPEH in ABC", description: "Contact: [email protected]↵+14692669295↵…WCDMA, we are not able to schedule GPEH in ABC. I", urgency: "4-Low", severity: "4-Minor/Localized"},
{id: "INC000000004512", title: "SR Updated - P3 - 2018-0427-0305 - xyz TELECOMMUNICATIONS ROMANIA S.R.L - Lost the  mng connect", description: null, urgency: "4-Low", severity: "4-Minor/Localized"},
{id: "INC000000004414", title: "Acme incident 1 title", description: "Acme incident 1 description", urgency: "2-High", severity: "1-Extensive/Widespread"}];


// trying to search for string in keys defined in defConfigs
items.filter(item =>
defConfigs.forEach((def) => {
  //iterate through all attributes in the object
  for(var key in item){
    //check if the attribute exists, if it has the method 'indexOf' (if it's a string), and that it has def.key in the string
    if (item[key] && item[key].indexOf && item[key].indexOf(def.key)!= -1) {
      //match only accepts regular expressions which are signified in JS by enclosing the expression with forward slashes
      return (item[def.key].toString().toLowerCase().match(/low/).length >1);
    }
   }
}));
Ответ принят как подходящий

Если вы присмотритесь, то заметите, что:

  1. Вы не проверяете, соответствует ли .match (он возвращает null при отсутствии совпадения; тестирование на null.length выдаст ошибку)
  2. Вы проверяете match.length > 1 ... используемый синтаксис вернет массив с ровно одним элементом или нулем
  3. Вам не хватает заявления на возврат для .filter.
  4. Вы не назначаете возвращаемое значение .filter какой-либо переменной.

Вот что вам нужно сделать:

var filteredItems = items.filter(function (item) {
    return defConfigs.some(function (def) {
        return (def.key in item)
            ? item[def.key].toString().toLowerCase().match('low') !== null
            : false;
    });
});
console.info(filteredItems);

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