Поиск JSON глубоко вложенных объектов с динамическими ключами с использованием Lodash? - PullRequest
0 голосов
/ 14 мая 2018

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

Например, если у меня есть:

"data": [
    { 
        "name": "Bob's concourse"
        "activities": [
             {
                 "day": "Monday",
                 "routines":
                     {
                         "Biking": 
                         {
                             "details": "won 3 trophies"
                             "type": "road"
                         },
                         "Kayaking":
                         {
                             "details": "participated in 3 races"
                             "type": "rhythm"
                         }
                      }
                 }
             }
        ]
    },

    {..other_data_etc...},

]
  • activities может быть []; не гарантируется, что он содержит какие-либо данные.
  • routines клавиши являются динамическими. то есть Biking, Kayaking являются динамическими строками. Это может быть что угодно.

Если я хочу найти races (без учета регистра), я хочу искать именно в:

  • data.name
  • data.activities.routines.* (динамические клавиши)
  • data.activities.routines.*.details

Если какой-либо из этих совпадений совпадет, он вернет корневой объект: { "name": "Bob", ..... }

Мне удалось вернуть name:

function searchText(collection, searchterm) {
    return _.filter(collection, function(o) { 
        return _.includes(o.name.toLowerCase(), searchterm)
    } );
};

Но я все еще новичок в lodash, и мне не удалось заставить ни один из вложенных поисков вернуться правильно, особенно с частью динамических ключей.

Может кто-нибудь помочь объяснить решение?

1 Ответ

0 голосов
/ 14 мая 2018

Расширение существующей попытки с помощью lodash:

const obj = {
  data: [{
    name: 'Bob\'s concourse',
    activities: [{
      day: 'Monday',
      routines: {
        Biking: {
          details: 'won 3 trophies',
          type: 'road'
        },
        Kayaking: {
          details: 'participated in 3 races',
          type: 'rhythm'
        }
      }
    }]
  }]
};

function search(str, data) {
  const searchStr = str.toLowerCase();

  // Only return the entries that contain a matched value
  return _.filter(data, (datum) => {
    // Check if name matches
    return _.includes(datum.name, searchStr)
    || _.some(datum.activities, (activity) => {
        return _.entries(activity.routines).some(([routine, {details}]) => {
          // Check if dynamic routine matches or details
          return _.includes(routine, searchStr) || _.includes(details, searchStr);
        });
      });
  });
}

console.log(search('foobar', obj.data));
console.log(search('races', obj.data));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>

Вы также можете сделать это с помощью простого JavaScript.Использование некоторого нового синтаксиса, такого как деструктурирующее присваивание , и новых собственных методов, таких как Object.entries, по существу следует той же схеме, что и использование lodash:

const obj = {
  data: [{
    name: 'Bob\'s concourse',
    activities: [{
      day: 'Monday',
      routines: {
        Biking: {
          details: 'won 3 trophies',
          type: 'road'
        },
        Kayaking: {
          details: 'participated in 3 races',
          type: 'rhythm'
        }
      }
    }]
  }]
};

function search(str, data) {
  const regex = RegExp(str, 'i');

  // Only return the entries that contain a matched value
  return data.filter((datum) => {
    // Check if name matches
    return regex.test(datum.name)
    || datum.activities.some((activity) => {
        return Object.entries(activity.routines).some(([routine, {details}]) => {
          // Check if dynamic routine matches or details
          return regex.test(routine) || regex.test(details);
        });
      });
  });
}

console.log(search('foobar', obj.data));
console.log(search('races', obj.data));
...