Найдите объекты определенной длины внутри объекта

Мне нужно пройтись по json-объекту и найти ключи-объекты, ключи-массивы, размер которых соответствует заданному значению.

Не могу понять где поставить условия.

function traverse(obj, size) {
    for (let key in obj) {
        if (typeof obj[key] === "object" && obj[key] != null) {
            traverse(obj[key]);
            if (Object.keys(obj[key]).length > size) {
                console.info(key);
            } else if (Array.isArray(obj[key])) {
                if (obj[key].length > size) { 
                    console.info(key);
                }
            } 
        }
    }
}

Я пробовал переставлять условия if, но это не дало хороших результатов.

Образец тестового объекта

let objTest = {
    "id": "66100c8e58d0a40e97ce7753",
    "createdBy": "crm1",
    "attributes": {
        "accountsInfoMessages": [{
            "valueOzb": "Mijozning holati yoritilgan. Hisob yaratish mumkin emas. Mijoz ma'lumotlarini to'ldiring. Buning uchun \"Kartochkani tanrirlash\" tugmasini bosing.",
            "code": "notCreateAccount",
        }, {
            "valueOzb": "Mijozning holati yoritilgan. Hisob yaratish mumkin emas. Mijoz ma'lumotlarini to'ldiring. Buning uchun \"Kartochkani tanrirlash\" tugmasini bosing.",
            "code": "notCreateAccount",
        }, {
            "valueOzb": "Mijozning holati yoritilgan. Hisob yaratish mumkin emas. Mijoz ma'lumotlarini to'ldiring. Buning uchun \"Kartochkani tanrirlash\" tugmasini bosing.",
            "code": "notCreateAccount",
        }],
        "selectedCardProduct": null,
        "homePageId": null,
        "branch": null,
        "customerId": "1111",
        "selectForCurrencyTest": "111",
        "selectForFiltersCardType": {
            "values": [{
                "code": "01",
                "valueOzb": "HUMO"
            }, {
                "code": "02",
                "valueOzb": "UzCard",
            }, {
                "code": "03",
                "valueOzb": "Visa"
            }],
        },
        "selectForCurrency": [{
            "valueOzb": "Andor pesetasi",
            "code": "ADP"
        }, {
            "code": "AED",
            "valueOzb": "Birlashgan Arab Amirliklari dirhami"
        }, {
            "valueOzb": "Afg'ani",
            "code": "AFA"
        }, ]
    },
    "selectForCurrency": "Test"
}

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

Nina Scholz 23.04.2024 18:07
Поведение ключевого слова "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
1
90
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы вызываете traverse только с одним аргументом.

if (typeof obj[key] === "object" && obj[key] != null) {
    traverse(obj[key]); // here !
     //... rest of the code
}

должен быть

traverse(obj[key], size);

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

  1. Вы должны передать аргументы рекурсивным вызовам
  2. Вы можете добавить аккумулятор для сбора результата

let objTest = {id:"66100c8e58d0a40e97ce7753",createdBy:"crm1",attributes:{accountsInfoMessages:[{valueOzb:"Mijozning holati yoritilgan. Hisob yaratish mumkin emas. Mijoz ma'lumotlarini to'ldiring. Buning uchun \"Kartochkani tanrirlash\" tugmasini bosing.",code:"notCreateAccount"},{valueOzb:"Mijozning holati yoritilgan. Hisob yaratish mumkin emas. Mijoz ma'lumotlarini to'ldiring. Buning uchun \"Kartochkani tanrirlash\" tugmasini bosing.",code:"notCreateAccount"},{valueOzb:"Mijozning holati yoritilgan. Hisob yaratish mumkin emas. Mijoz ma'lumotlarini to'ldiring. Buning uchun \"Kartochkani tanrirlash\" tugmasini bosing.",code:"notCreateAccount"}],selectedCardProduct:null,homePageId:null,branch:null,customerId:"1111",selectForCurrencyTest:"111",selectForFiltersCardType:{values:[{code:"01",valueOzb:"HUMO"},{code:"02",valueOzb:"UzCard"},{code:"03",valueOzb:"Visa"}]},selectForCurrency:[{valueOzb:"Andor pesetasi",code:"ADP"},{code:"AED",valueOzb:"Birlashgan Arab Amirliklari dirhami"},{valueOzb:"Afg'ani",code:"AFA"},]},selectForCurrency:"Test"};

function traverse(obj, size, key = null, result = []) {
  if (Array.isArray(obj)){
    obj.forEach((item,i) => traverse(item, size, i, result));
    obj.length > size && key && result.push(key);
  } else if (obj && typeof obj === "object") {
    const keys = Object.keys(obj);
    keys.forEach(key => traverse(obj[key], size, key, result));
    keys.length > size && key && result.push(key);
  }
  return result;
}

console.info(traverse(objTest, 1));

Спасибо за ваш ответ. Функция возвращает пустой массив. Я не смог отладить, где находится ошибка. Я прикрепил тестовый объект.

Alexander Wang 24.04.2024 10:29
Ответ принят как подходящий

Насколько я понимаю, я исправил некоторые части вашей функции. Это должно сработать. Если это не так, дайте мне знать в комментариях, с какой ошибкой/ошибкой вы столкнулись. Предпочтительно добавить в свой вопрос экземпляр/упрощенный пример объекта, который вы проходите.

Обновлено: Вот окончательный вариант протестированного решения:

/* Test Data: */
const testObject = {
  owner: 'John Doe',
  prices: [200, 450, -400, 3000, -650, -130, 70, 1300],
  interestRate: 1.2, // %
  pin: 1111,
  nullVal: null,
  objOuter: {
    one: 1,
    two: 2,
    three: 3,
    arr1: [200, 450, -650],
    inner: {
      uno: 1,
      dos: 2,
      tres: 3,
      arr2: [-400, 3000],
      innermost: {
        ich: 1,
        ni: 2,
        san: 3,
        arr3: [-130, 70, 1300],
      },
    },
  },
};

/* Function: */
function traverse(obj, size) {
  for (const [key, val] of Object.entries(obj)) {
    if (!val) continue;
    if (Array.isArray(val) && val.length > size) {
      console.info(key);
      val.forEach(function (el, i) {
        if (typeof el === 'object') traverse(el, size);
      });
    }
    if (typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length > size) {
      console.info(key);
      traverse(val, size);
    }
  }
}
traverse(testObject, 3); // Function call

Спасибо. Похоже, это работает. Проблема заключалась только в том, что при проверке массива значение равно нулю: Object.keys(val) не может преобразовать значение null. Я добавил проверку на null if (typeof val === 'object' && val != null && !Array.isArray(val) && Object.keys(val).length > size)

Alexander Wang 24.04.2024 10:15

Вам не нужно проверять наличие «нулевых» значений, потому что об этом позаботится условие (typeof val === "object"). Если val является типом object, его значение не будет нулевым, даже если оно пустое. Точно так же, как console.info({}); и console.info([]); не печатают null. Если val — пустой объект/массив, условие, проверяющее его размер/длину, будет false и val будет игнорироваться.

Rishikesh Negi 24.04.2024 10:27

Без проверки выдается сообщение «TypeError: невозможно преобразовать неопределенное или нулевое значение в объект» в Object.keys(val). Я прикрепил образец объекта.

Alexander Wang 24.04.2024 10:33

Да. Кажется, это так. Чтобы исправить это правильно, я предлагаю добавить эту строку: if (!val) continue; в начало цикла for-of в функции. Я добавляю эту строку в окончательную версию ответа.

Rishikesh Negi 24.04.2024 10:53

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