118 votes

Recherche par clé profonde dans un tableau imbriqué

Disons que j'ai un objet :

[
    {
        'title': "some title"
        'channel_id':'123we'
        'options': [
                    {
                'channel_id':'abc'
                'image':'http://asdasd.com/all-inclusive-block-img.jpg'
                'title':'All-Inclusive'
                'options':[
                    {
                        'channel_id':'dsa2'
                        'title':'Some Recommends'
                        'options':[
                            {
                                'image':'http://www.asdasd.com'                                 'title':'Sandals'
                                'id':'1'
                                'content':{
                                     ...

Je veux trouver l'objet dont l'identifiant est 1. Existe-t-il une fonction pour quelque chose comme ça ? Je pourrais utiliser la fonction Underscore _.filter mais je devrais commencer par le haut et filtrer vers le bas.

3voto

vincent Points 395

Nous utilisons balayage de l'objet pour le traitement de nos données. C'est conceptuellement très simple, mais cela permet de faire beaucoup de choses intéressantes. Voici comment vous pourriez résoudre votre question spécifique

// const objectScan = require('object-scan');

const find = (id, input) => objectScan(['**'], {
  abort: true,
  rtn: 'value',
  filterFn: ({ value }) => value.id === id
})(input);

const data = [{ title: 'some title', channel_id: '123we', options: [{ channel_id: 'abc', image: 'http://asdasd.com/all-inclusive-block-img.jpg', title: 'All-Inclusive', options: [{ channel_id: 'dsa2', title: 'Some Recommends', options: [{ image: 'http://www.asdasd.com', title: 'Sandals', id: '1', content: {} }] }] }] }];

console.log(find('1', data));
// => { image: 'http://www.asdasd.com', title: 'Sandals', id: '1', content: {} }

.as-console-wrapper {max-height: 100% !important; top: 0}

<script src="https://bundle.run/object-scan@13.8.0"></script>

Avis de non-responsabilité : Je suis l'auteur de balayage de l'objet

3voto

Thiago Lagden Points 91

Il suffit d'utiliser la fonction récursive.
Voir l'exemple ci-dessous :

const data = [
  {
    title: 'some title',
    channel_id: '123we',
    options: [
      {
        channel_id: 'abc',
        image: 'http://asdasd.com/all-inclusive-block-img.jpg',
        title: 'All-Inclusive',
        options: [
          {
            channel_id: 'dsa2',
            title: 'Some Recommends',
            options: [
              {
                image: 'http://www.asdasd.com',
                title: 'Sandals',
                id: '1',
                content: {},
              }
            ]
          }
        ]
      }
    ]
  }
]

function _find(collection, key, value) {
  for (const o of collection) {
    for (const [k, v] of Object.entries(o)) {
      if (k === key && v === value) {
        return o
      }
      if (Array.isArray(v)) {
        const _o = _find(v, key, value)
        if (_o) {
          return _o
        }
      }
    }
  }
}

console.log(_find(data, 'channel_id', 'dsa2'))

3voto

FuZu Points 1

J'ai trouvé la réponse que je cherchais, notamment la solution d'Ali Alnoaimi. J'ai fait quelques petits ajustements pour permettre la recherche de la valeur également

function deepSearchByKey(object, originalKey, originalValue, matches = []) {
if (object != null) {
  if (Array.isArray(object)) {
    for (let arrayItem of object) {
      deepSearchByKey(arrayItem, originalKey, originalValue, matches);
    }
  } else if (typeof object == 'object') {
    for (let key of Object.keys(object)) {
      if (key == originalKey) {
        if (object[key] == originalValue) {
          matches.push(object);
        }
      } else {
        deepSearchByKey(object[key], originalKey, originalValue, matches);
      }
    }
  }
}

return matches;
}

A utiliser :

let result = deepSearchByKey(arrayOrObject, 'key', 'value');

Cela renverra l'objet contenant la clé et la valeur correspondantes.

2voto

Villarrealized Points 572

La réponse de @Iulian Pinzaru était presque exactement ce dont j'avais besoin, mais elle ne fonctionne pas si vos objets ont des valeurs nulles. Cette version corrige cela.

function  deepSearch (object, key, predicate) {
  if (object.hasOwnProperty(key) && predicate(key, object[key]) === true) return object

  for (let i = 0; i < Object.keys(object).length; i++) {
    const nextObject = object[Object.keys(object)[i]];
    if (nextObject && typeof nextObject === "object") {
      let o = deepSearch(nextObject, key, predicate)
      if (o != null) return o
    }
  }
  return null
}

2voto

Surya Points 21
          function getPropFromObj(obj, prop) {
            let valueToFindByKey;
            if (!Array.isArray(obj) && obj !== null && typeof obj === "object") {
              if (obj.hasOwnProperty(prop)) {

                 valueToFindByKey = obj[prop];
               console.log(valueToFindByKey);
              } else {

                let i;
                for (i = 0; i < Object.keys(obj).length; i++) {

                    getPropFromObj(obj[Object.keys(obj)[i]], prop);
                }
              }

            }
            return null;

          }

        const objToInvestigate = {
            employeeInformation: {
              employees: {
                name: "surya",
                age: 27,
                job: "Frontend Developer",
              },
            },
          };
          getPropFromObj(objToInvestigate, "name");
  1. Détection de la clé dans l'objet profondément imbriqué.
  2. Enfin, retournez la valeur de la clé détectée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X