Фильтр Javascript Объект JSON, не являющийся массивом

Я пытаюсь отфильтровать объект JSON, не являющийся массивом, как следующий фрагмент

const filter = { filterRows: ['one'] };

const templateMapper = {
  'one': {
    title: 'one',
  },
  'two': {
    title: 'two',
  },
  'three': {
    title: 'three',
  },
}

const filterDialogView = filter.filterRows;
const filterTemplateMapper = [templateMapper].filter(row => !filterDialogView.includes(row));
console.info(filterTemplateMapper);

Но это не фильтрация

Я получаю следующий вывод

[
  {
    "one": {
    "title": "one"
  },
  "two": {
    "title": "two"
  },
  "three": {
    "title": "three"
  }
 }
]

Выход желания

 {
  "two": {
    "title": "two"
  },
  "three": {
    "title": "three"
  }
 }

Я хочу отфильтровать строку на основе filterRows, например, если filterRows содержит one, как указано выше, JSON, тогда one следует удалить из templateMapper

где JSON? все, что я вижу, это объект... и объекты не могут быть отфильтрованы с помощью Array.filter, потому что у объектов нет метода фильтра

Jaromanda X 21.05.2019 07:56

я использую [templateMapper], см. приведенный выше код, который я использовал [] массивы

user11229655 21.05.2019 07:57

Да, но в этом массиве одна запись — объект ВЕСЬ.

Jaromanda X 21.05.2019 08:04
Поведение ключевого слова "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) для оценки ваших знаний,...
3
3
601
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Один из вариантов — создать копию объекта templateMapper, затем выполнить итерацию по filterRows и удалить каждый связанный ключ:

const filter = {
  filterRows: ['one']
};

const templateMapper = {
  'one': {
    title: 'one',
  },
  'two': {
    title: 'two',
  },
  'three': {
    title: 'three',
  },
};


const filterTemplateMapper = { ...templateMapper };
filter.filterRows.forEach((key) => {
  delete filterTemplateMapper[key];
});
console.info(filterTemplateMapper);

(также, как примечания к комментариям, Не существует такого понятия, как «объект JSON».)

Это изменяет объект, а не создает новый, что отличается от того, как работает метод фильтра.

Soviut 21.05.2019 07:58

Он не изменяет исходный объект — { ...templateMapper } создает копию.

CertainPerformance 21.05.2019 07:59

Вы можете сначала filterentries объекта. Затем используйте Object.fromEntries(), чтобы создать новый объект из этих отфильтрованных записей.

const filter = { filterRows: ['one'] };

const templateMapper = {
  'one': {
    title: 'one',
  },
  'two': {
    title: 'two',
  },
  'three': {
    title: 'three',
  },
}

const filteredObject = Object.fromEntries(
    Object.entries(templateMapper).filter(([k]) => !filter.filterRows.includes(k))
)

console.info(filteredObject)

Вы можете filter() объекты. Вы должны filter() записи объекта, а затем снова преобразовать его в объект, используя Object.fromEntries()

const filter = { filterRows: ['one'] };

const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }

const filterDialogView = filter.filterRows;
const filterTemplateMapper = Object.fromEntries(
             Object.entries(templateMapper)
                   .filter(row => !filterDialogView.includes(row[0].title))
             );
console.info(filterTemplateMapper);

Если Object.fromEntries() не поддерживается вашим браузером, используйте reduce()

const filter = { filterRows: ['one'] };

const templateMapper = { 'one': { title: 'one', }, 'two': { title: 'two', }, 'three': { title: 'three', }, }

const filterDialogView = filter.filterRows;
const filterTemplateMapper = Object.entries(templateMapper)
                   .filter(row =>!filterDialogView.includes(row[0].title))
                   .reduce((ac,[k,v]) => (ac[k] = v,ac),{});
console.info(filterTemplateMapper);
Ответ принят как подходящий

Вы можете использовать Объект.fromEntries для создания объекта из отфильтрованных записей.

Здесь идея: -

  • Сначала получите записи из объекта шаблона
  • Фильтровать записи на основе значения фильтра
  • Используйте Объект.fromEntries для создания объекта из отфильтрованных записей.

const filter = { filterRows: ['one'] };

const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}}

const filterDialogView = filter.filterRows;
const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row))
console.info(Object.fromEntries(final));

Если ваша среда не поддерживает Object.fromEntries, вы можете использовать это

const filter = { filterRows: ['one'] };

const template = {'one': {title: 'one',},'two': {title: 'two',},'three': {title: 'three',}}

const filterDialogView = filter.filterRows;
const final = Object.entries(template).filter(([row])=> !filterDialogView.includes(row))

const output = final.reduce((op,[key,value])=>{
  op[key] = value
  return op
},{})
console.info(output);

Это лучший ответ (я собирался опубликовать идентичный код) - я бы также добавил несколько замечаний по поводу Object.fromEntries

Jaromanda X 21.05.2019 08:01

@JaromandaX, спасибо, приятель :), я добавил описание кода и соответствующую ссылку,

Code Maniac 21.05.2019 08:06

@CodeManiac я получаю эту ошибку Object.fromEntries не является функцией в Node.JS

user11229655 21.05.2019 08:14

@ user11229655, какую версию узла вы используете, приятель?

Code Maniac 21.05.2019 08:15

я использую узел v10.15.2

user11229655 21.05.2019 08:15

@CodeManiac, который я пробовал в узле REPL.it, кажется, проблема с v10.15.2. также попробовал реагировать, все работает нормально, спасибо

user11229655 21.05.2019 08:21

@user11229655 user11229655 я не уверен в совместимости с узлом, если он несовместим с этой версией, вы можете добавить полифилл для Object.fromEntries или использовать reduce для создания объекта

Code Maniac 21.05.2019 08:21

Вместо изменения исходного объекта создайте его копию и удалите ненужные ключи. Для удаления вы можете использовать ключевое слово delete. Повторил массив filterRows, а затем использовал delete для удаления ключей из скопированного объекта.

const filter = {
  filterRows: ['one']
};

const templateMapper = {
  'one': {
    title: 'one',
  },
  'two': {
    title: 'two',
  },
  'three': {
    title: 'three'
  },
}


let newObj = JSON.parse(JSON.stringify(templateMapper));
filter.filterRows.forEach(function(item) {
  if (newObj.hasOwnProperty(item)) {
    delete newObj[item]
  }
});
console.info(newObj)

Функция filter() доступна только для массивов. Чтобы получить такое же поведение с объектом, вам нужно использовать entries() объекта.

const filter = {
  filterRows: ['one']
}

const templateMapper = {
  'one': {
    title: 'one',
  },
  'two': {
    title: 'two',
  },
  'three': {
    title: 'three',
  },
}

const filteredMapper = Object.entries(templateMapper).reduce((acc, [key, value]) => {
  // if the key is not in the filtered list, add this entry to the object
  if (!filter.filterRows.includes(key)) {
    acc[key] = value
  }

  return acc
}, {}) // pass in empty object as initial value of accumulator

console.info(filteredMapper)

Это работает следующим образом: сначала мы получаем entries (пары ключ/значение) из templateMapper. Затем мы берем эти записи и reduce их. Сокращение принимает несколько аргументов, включая «аккумулятор», который собирает поля, которые мы хотим сохранить. Мы «деструктурируем» key и value, чтобы мы могли проверить, есть ли ключ в списке фильтров. Если фильтровать не будем, добавляем из аккумулятора. Затем мы возвращаем аккумулятор для следующей итерации сокращения. Наконец, мы передаем пустой объект в качестве начального значения для аккумулятора на первой итерации.

Вы можете использовать этот способ:

const filter = { filterRows: ['one'] };

const templateMapper = {
  'one': {
    title: 'one',
  },
  'two': {
    title: 'two',
  },
  'three': {
    title: 'three',
  },
}

// Convert object templateMapper to array with key
const keyArrayTemplateMapper = Object.keys(templateMapper);

// Filter key array
const filterKey = keyArrayTemplateMapper.filter(key => !filter.filterRows.includes(key));

// Using reduce method to return new array
const output = filterKey.reduce((obj, key) => {
    obj[key] = templateMapper[key];
    return obj;
  }, {});

console.info(output);

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

Maheer Ali 21.05.2019 08:13

Я не вижу ничего плохого в вашем коде, единственное, чего не хватает, - это какое-то объяснение, приятель, считается хорошей практикой добавить объяснение к вашему ответу, поскольку это поможет будущим читателям.

Code Maniac 21.05.2019 08:14

Я понял, добавил некоторые пояснения. Спасибо вам, ребята.

Scofjeld 21.05.2019 08:29

@Scofield, вы можете сделать свой код исполняемым фрагментом кода читать здесь, и вот ваши награды за подробный ответ

Code Maniac 21.05.2019 08:32

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