Найти совпадающее имя свойства в объекте и вернуть его значение

#javascript #node.js

#javascript #node.js

Вопрос:

У меня есть неизвестный структурированный объект JSON, который я хочу прочитать все его свойства и вернуть его значение, когда условие будет выполнено.

 {
      "tags": ["a", "b", "c"],
      "image": "path/to/thumbnail.png",
      "description": "First level description",
      "name": "First name",
      "another": {
        "abcde": {
          "label": "one two three",
          "description": "Oopsy!"
        },
        "fghijk": {
          "label": "Label ABC :)",
          "description": "Is not a song here bruh!"
        }
      },
      "couldBeEmpty": {},
      "couldBeLast": {
        "someCoolName": {
          "label": "Some label here you know",
          "description": "Another Desc Again",
          "type": "text"
        },
        "someLabelAgain": {
          "label": "Just a label name",
          "description": "Yep another Desc :)",
          "type": "color"
        },
        "someObjLabel": {
          "label": "Another label name",
          "description": "Desc label here too",
          "type": "text"
        },
        "ahCoolThing": {
          "label": "Some label for this too",
          "description": "Desc here is fine too",
          "type": "color"
        },
        "couldBeLastInHere": {
          "label": "label",
          "description": "Desc goes here",
          "type": "color"
        }
      }
    }
 

Я хочу получить все имя, метку и описание для любой заданной структуры объекта, а затем создать новый объект примерно таким

 {
  "description": "First level description",
  "name": "First name",
  "abcde/label": "one two three",
  "abcde/description": "Oopsy!"
  "fghijk/label": "Label ABC :)",
  "fghijk/description": "Is not a song here bruh!"
  "someCoolName/label": "Some label here you know",
  "someCoolName/description": "Another Desc Again",
  "someLabelAgain/label": "Just a label name",
  "someLabelAgain/description": "Yep another Desc :)",
  "someObjLabel/label": "Another label name",
  "someObjLabel/description": "Desc label here too",
  "ahCoolThing/label": "Some label for this too",
  "ahCoolThing/description": "Desc here is fine too",
  "couldBeLastInHere/label": "label",
  "couldBeLastInHere/description": "Desc goes here"
}
 

Прямо сейчас я пытаюсь использовать Lodash для этого, но не смог найти способ найти все свойства с заданным именем, кроме необходимости перебирать все

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

1. Почему бы просто не закодировать рекурсивный цикл самостоятельно?

2. У меня есть цикл 3 for, потому что у меня есть ожидаемая версия объекта, но я не совсем уверен, как правильно это сделать, и вы просто напоминаете мне о рекурсивном цикле! O_o

Ответ №1:

То, что вы ищете, по сути, является пользовательской функцией сокращения (вы пытаетесь уменьшить объект до некоторого сжатого представления его данных). Вот реализация, которая позволяет вам указать, какие поля вы хотите извлечь:

 function myReduce(o, fields, p, c) {
    // p: path
    // c: context (accumulator)
    if(p===undefined) p = '', c = {};
    for(var prop in o) {
        if(!o.hasOwnProperty(prop)) continue;
        if(fields.indexOf(prop)!=-1) c[p   prop] = o[prop];
        else if(typeof o[prop]==='object') myReduce(o[prop], fields, prop   '/', c);
    }
    return c;
}
 

Чтобы получить интересующие вас поля, вы должны назвать это так:

 myReduce(data, ['name', 'label', 'description']);
 

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

1. Проще, чем то, что у меня есть для трех циклов! Большое вам спасибо!!

2. Вы это заслужили! Я for in был в три раза глубже и не думал делать это так (я думаю, что уже очень поздно, и мой мозг замедляется в 100 раз)