#javascript #node.js #algorithm #data-structures
#язык JavaScript #node.js #алгоритм #структуры данных
Вопрос:
У меня есть код, который будет фильтровать данные в соответствии с указанным набором ключей. До сих пор мой код обрабатывает, являются ли передаваемые данные массивом или объектом определенного типа. Например, объект автомобиля или массив объектов автомобиля, а ключевым списком будут атрибуты автомобиля. Тем не менее, я только что получил новый набор данных, и мне интересно, как лучше всего с ним обращаться. Вот мой код до сих пор (не беспокойтесь слишком сильно о проверке моего массива/объекта, у меня есть пользовательские функции, которые выполняют гораздо больше проверок)
const goodDataObject = { "make": "toyota", "model": "rav4", "color": "white" "mileage": "10000", "engine": "hybrid" }; const goodDataArray = [ { "make": "toyota", "model": "rav4", "color": "white" "mileage": "10000", "engine": "hybrid" }, { "make": "chevrolet", "model": "cruze", "color": "black" "mileage": "20000", "engine": "gas" } ] const badDataObject = { "dealer": "John Does Cars", "factory": "Michigan", "cars": [ { "make": "toyota", "model": "rav4", "color": "white" "mileage": "10000", "engine": "hybrid" }, { "make": "chevrolet", "model": "cruze", "color": "black" "mileage": "20000", "engine": "gas" } ] } // --gt;gt; results from goodDataObject: { "make": "toyota", "model": "rav4" } // --gt;gt; results from goodDataArray: [ { "make": "toyota", "model": "rav4" }, { "make": "chevrolet", "model": "cruze" } ] // --gt;gt; results I WANT from badDataObject: { "dealer": "John Does Cars", "factory": "Michigan", "cars": [ { "make": "toyota", "model": "rav4" }, { "make": "chevrolet", "model": "cruze" } ] }
Вот мой текущий код, вызываемый с помощью ключей ["make", "model"]
.
function filterData(data, keys) { let filtered = null; if (typeof data === 'object') { for (let x of keys) { filtered[x] = data[x] } } else if (Array.isArray(data)) { filtered = []; for (let y of data) { let filteredObject = {}; for (let key of keys) { filteredObject[key] = y[key]; } filtered.push(filteredObject); } } return filtered; }
Мне нужно обработать объект badDataObject, и я думал о рекурсивном варианте, но пока это не увенчалось успехом, поэтому я не могу там много публиковать
Обновление: Ключи являются примерами, но я должен справиться со всеми. Кроме того, примером может служить объект badDataObject. cars
может быть vans
или trucks
и т. Д.
Комментарии:
1. Как вы различаете
dealer
то , с чем вы не справляетесь, иcars
то , что вы делаете? Что делать, если вdealer
собственности был объект сmodel
ребенком? Кроме того, могут ли объекты, которые вы хотите спроектировать, быть вложены произвольно глубоко? Если да, то как вы решаете, на каких уровнях проводить проекцию?
Ответ №1:
Если вы уверены, что badDataObject будет содержать ключ «автомобили», то вам следует просто отфильтровать, извлекая только этот ключ.
В противном случае вы можете написать рекурсивную функцию, которая определяет, содержит ли какой-либо ключ данные(массив или объект), содержащие нужные ключи, но я думаю, что это было бы излишним и сложным в управлении.
Ответ №2:
Я думаю, что ваши требования не совсем ясны, как я уже упоминал в комментариях. Но, угадав их, мы можем написать что-то, что ищет подобъекты, обладающие ключевыми свойствами, которые мы ищем, а затем сохранить только их, сохранив все, где отсутствует какой-либо из этих ключей. Это может выглядеть так:
const map = (fn) =gt; (o) =gt; Array .isArray (o) ? o .map (fn) : Object .fromEntries (Object .entries (o) .map (([k, v]) =gt; [k, fn (v)])) const select = (ks) =gt; (o) =gt; Object (o) === o ? ks .every (k =gt; k in o) ? Object .fromEntries (ks .map (k =gt; [k, o [k]])) : map (select (ks)) (o) : o const goodDataObject = {make: "toyota", model: "rav4", color: "white", mileage: "10000", engine: "hybrid"} const goodDataArray = [{make: "toyota", model: "rav4", color: "white", mileage: "10000", engine: "hybrid"}, {make: "chevrolet", model: "cruze", color: "black", mileage: "20000", engine: "gas"}] const badDataObject = {dealer: "John Does Cars", factory: "Michigan", cars: [{make: "toyota", model: "rav4", color: "white", mileage: "10000", engine: "hybrid"}, {make: "chevrolet", model: "cruze", color: "black", mileage: "20000", engine: "gas"}]} console .log ('goodDataObject:', select (['make', 'model']) (goodDataObject)) console .log ('goodDataArray:', select (['make', 'model']) (goodDataArray)) console .log ('badDataObject:', select (['make', 'model']) (badDataObject))
.as-console-wrapper {max-height: 100% !important; top: 0}
Вот map
вспомогательная функция, которая вызывает Array.prototype.map
массивы и делает что-то довольно эквивалентное для объектов. ( map (n =gt; n ** 2) ({a: 1, b: 2, c: 3})
возвращается {a: 1, b: 4, c: 9}
.)
Наша основная функция select
принимает массив целевых ключей и возвращает функцию, которая принимает объект, проверяет, есть ли у него все целевые ключи. Если их там нет, он возвращается к своим детям. Если это так, он извлекает только эти ключи. И если это вообще не объект, он возвращает его в целости и сохранности.
Вы можете увидеть поведение более сложного объекта, такого как этот:
{ company: "Acme Corp", office: "Chicago", companyCars: [ {make: "toyota", model: "rav4", color: "white", mileage: "10000", engine: "hybrid"}, {make: "chevrolet", model: "cruze", color: "black", mileage: "20000", engine: "gas"} ], departments: { marketing: { director: 'Susan', car: {make: "dodge", model: "neon", color: "red", mileage: "10000", engine: "gas"}, }, sales: { local: { manager: 'Peter', fleet: [ {make: "toyota", model: "rav4", color: "blue", mileage: "30000", engine: "hybrid"}, {make: "chevrolet", model: "cruze", color: "green", mileage: "50000", engine: "gas"} ] }, state: { manager: 'Edmond' }, national: { manager: 'Lucy', marketingVehicle: {make: "Prevost", model: "X3-45", engineHours: "900", paintjob: "purple logo"}, } } } }
Он вернет это:
{ company: "Acme Corp", office: "Chicago", companyCars: [ {make: "toyota", model: "rav4"}, {make: "chevrolet", model: "cruze"} ], departments: { marketing: { director: "Susan", car: {make: "dodge", model: "neon"} }, sales: { local: { manager: "Peter", fleet: [ {make: "toyota", model: "rav4"}, {make: "chevrolet", model: "cruze"} ] }, state: { manager: "Edmond" }, national: { manager: "Lucy", marketingVehicle: {make: "Prevost", model: "X3-45"} } } } }
Ответ №3:
Должно быть легко сделать с помощью Array.map()
.
Я обновил функцию, так что теперь она также принимает объект, описывающий, какие данные вам нужны.
const badDataObject = { "dealer": "John Does Cars", "factory": "Michigan", "cars": [{ "make": "toyota", "model": "rav4", "color": "white", "mileage": "10000", "engine": "hybrid" }, { "make": "chevrolet", "model": "cruze", "color": "black", "mileage": "20000", "engine": "gas" } ] }; function goodDataObject(data, target) { for (const prop in target){ data[prop] = data[prop].reduce((acc, item) =gt; { const obj = {}; for(const key of target[prop]){ if(key in item) obj[key] = item[key]; } acc.push(obj); return acc; }, []); } return data; } console.log(goodDataObject( badDataObject, { cars: [ "model", "make"]} ))
Комментарии:
1. Я обновил, чтобы упомянуть, что мои ключи и объект badDataObject являются примерами. Мне нужно обработать все возможные ключи, и машины-это всего лишь пример. Извините, что не совсем ясно выразился
2. @johnny_mac Я обновил код, так что вы можете выбрать нужные вам данные.