3
votes

Objet du tableau d'objets. Obtenir la longueur de toutes les valeurs avec la même propriété

J'ai un objet qui ressemble à ceci:

    var obj = {
      "array1": [
        {
          "label": "something1",
          "ref": "option2a"
        },
        {
          "label": "something2",
          "ref": "option2b"
        },
        {
          "label": "something3",
          "ref": "option2a"
        },
        {
          "label": "something4",
          "ref": "option2a"
        },
        {
          "label": "something5",
          "ref": "option2a"
        }
      ],
      "array2": [
        {
          "label": "something6 is the longest label",
          "ref": "option3a"
        },
        {
          "label": "Other",
          "ref": "option3b"
        }
      ]
    }

Je veux obtenir la longueur de l'étiquette la plus longue. Dans ce cas, je voudrais retourner 17. Parce que l'étiquette la plus longue est "quelque chose de plus long" qui a une longueur de 17.


3 commentaires

Qu'est-ce que tu as essayé jusque-là?


La longueur de somethinglongest n'est que de 16 ...


Bonne question. L'utilisation de map () et ... (notation à trois points) pour déstructurer un tableau est vraiment excellente.


6 Réponses :


4
votes
  • Utilisez .concat () et Object.values ​​() pour obtenir un seul tableau contenant tous les objets.
  • Utilisez .map () pour un tableau contenant une longueur de chaînes.
  • Et enfin, utilisez .reduce () pour obtenir la longueur de la chaîne la plus longue.
  • let data = {
        "array1": [
            {"label": "something1", "ref": "option2a"},
            {"label": "something2", "ref": "option2b"},
            {"label": "something3", "ref": "option2a"},
            {"label": "something4", "ref": "option2a"},
            {"label": "something5", "ref": "option2a"}
        ],
        "array2": [
            {"label": "somethinglongest", "ref": "option3a"},
            {"label": "Other", "ref": "option3b"}
        ]
    };
    
    let reducer = arr => [].concat(...Object.values(arr))
                           .map(({ label }) => label.length)
                           .reduce((r, c) => r > c ? r : c);
    
    console.log(reducer(data));

1 commentaires

La lisibilité est utile ici.



4
votes

Obtenez un tableau de tous les objets à l'intérieur des sous-tableaux.

Calculez la longueur maximale des valeurs mappant chaque valeur à sa longueur:

var obj = {
  "array1": [{
      "label": "something1",
      "ref": "option2a"
    },
    {
      "label": "something2",
      "ref": "option2b"
    },
    {
      "label": "something3",
      "ref": "option2a"
    },
    {
      "label": "something4",
      "ref": "option2a"
    },
    {
      "label": "something5",
      "ref": "option2a"
    }
  ],
  "array2": [{
      "label": "somethinglongest",
      "ref": "option3a"
    },
    {
      "label": "Other",
      "ref": "option3b"
    }
  ]
};

console.log(Math.max(...Object.values(obj).flat().map(o => o.label.length)));


3 commentaires

+1 pour la méthode flat . Vous pouvez le faire sans réduire Math.max (... Object.values ​​(obj) .flat (). Map (o => o.label.length))


Dans l'espoir d'être constructif - pourquoi effectuer autant d'opérations en 1 ligne? N'est-ce pas difficile de grok au premier coup d'œil ou en revenant dans le futur pour s'ajuster?


@CharlieSchliesser simplement parce que je tapais plus vite et que je faisais tout en une fois. Mais n'importe qui peut extraire toutes les variables qu'il veut :)



1
votes

Une autre option consiste à parcourir les propres propriétés de l'objet obj et à vérifier si la longueur de chaque étiquette est plus longue que la longueur la plus longue précédente.

var obj = {
  "array1": [
    { "label": "something1", "ref": "option2a" },
    { "label": "something2", "ref": "option2b" },
    { "label": "something3", "ref": "option2a" },
    { "label": "something4", "ref": "option2a" },
    { "label": "something5", "ref": "option2a" }
  ], "array2": [ 
    { "label": "somethinglongest", "ref": "option3a" },
    { "label": "Other", "ref": "option3b" }
  ]
}

let longest = 0;

for (key in obj) {
  if(obj.hasOwnProperty(key)) {
    obj[key].forEach(item => {
      if (item.label.length > longest) longest = item.label.length;
    })
  }
}

console.log(longest);


0 commentaires

1
votes

Vous pouvez rechercher des objets puis la clé souhaitée. Cela fonctionne pour une profondeur de données arbitraire.

function getLongest(object, key) {
    return Object.values(object).reduce((l, v) => {
        if (key in v) return Math.max(l, v[key].length);
        if (v && typeof v === 'object') return Math.max(l, getLongest(v, key));
        return l;    
    }, 0);
}

var data = { array1: [{ label: "something1", ref: "option2a" }, { label: "something2", ref: "option2b" }, { label: "something3", ref: "option2a" }, { label: "something4", ref: "option2a" }, { label: "something5", ref: "option2a" }], array2: [{ label: "somethinglongest", ref: "option3a" }, { label: "Other", ref: "option3b" }] };

console.log(getLongest(data, 'label'));


0 commentaires

2
votes

Une approche simple:

let obj = {
      "array1": [
        {"label": "something1", "ref": "option2a"},
        {"label": "something2", "ref": "option2b"},
        {"label": "something3", "ref": "option2a"},
        {"label": "something4", "ref": "option2a"},
        {"label": "something5", "ref": "option2a"}
      ],
      "array2": [
        {"label": "something6 is the longest label", "ref": "option3a"},
        {"label": "Other", "ref": "option3b"}
      ]
};

let longest = 0
for (key in obj){
    if (!obj.hasOwnProperty(key)) continue;
    for (let x of obj[key]){
        if (x.label.length > longest)
            longest = x.label.length;
    }
}
console.log(longest);


6 commentaires

Merci, comment puis-je le faire fonctionner avec des étiquettes comportant des espaces?


J'obtiens l'erreur suivante: Uncaught TypeError: Impossible d'utiliser l'opérateur 'in' pour rechercher 'label' dans Calculate Your Total


@Mandalina J'ai bien peur de ne pas pouvoir vous aider car cette erreur est causée par votre propre code ... Si vous cliquez sur le bouton bleu "Exécuter l'extrait de code" dans la question, il est clair que mon code fonctionne bien.


Bonjour à nouveau @cybernaut J'ai ajouté une fois de plus à la question, comment cela fonctionnerait-il pour un objet contenant des objets et des tableaux?


@Mandalina Je suis désolé, une question par question! Vous devrez en demander un nouveau (vous pouvez le lier à celui-ci et je vais jeter un œil).


stackoverflow .com / questions / 54152210 /… @cybernaut



0
votes

Vous pouvez utiliser cette instruction sur 1 ligne.

> Math.max(4, 5, 7)
7
>
> Math.max([4, 5, 7])
NaN
>
> Math.max(...[6, 7])
7
>
> let a = [2, 4, 5]
undefined
>
> a2 = a.map((num) => num ** 2)
[ 4, 16, 25 ]
>
> a3 = a.map((num) => num + 2)
[ 4, 6, 7 ]
>

Exemple sur Node REPL

let keys = Object.keys(obj);

let maxLens = keys.map((key) => {
    let arr = obj[key];
    return Math.max(...arr.map((o) => o.label.length))
});

let max = Math.max(...maxLens);

console.log(keys);    // [ 'array1', 'array2' ]
console.log(maxLens); // [ 10, 16 ]
console.log(max);     // 16

Présentation détaillée

> var obj = {
...       "array1": [
...         {
.....           "label": "something1",
.....           "ref": "option2a"
.....         },
...         {
.....           "label": "something2",
.....           "ref": "option2b"
.....         },
...         {
.....           "label": "something3",
.....           "ref": "option2a"
.....         },
...         {
.....           "label": "something4",
.....           "ref": "option2a"
.....         },
...         {
.....           "label": "something5",
.....           "ref": "option2a"
.....         }
...       ],
...       "array2": [
...         {
.....           "label": "somethinglongest",
.....           "ref": "option3a"
.....         },
...         {
.....           "label": "Other",
.....           "ref": "option3b"
.....         }
...       ]
...     }
undefined
>
> Math.max(...Object.keys(obj).map((key) => Math.max(...obj[key].map((o) => o.label.length))))
16
>

Et voici l'exemple pour vous aider.

let maxLen = Math.max(...Object.keys(obj).map((key) => Math.max(...obj[key].map((o) => o.label.length))));


2 commentaires

Merci beaucoup pour votre réponse! J'ai mis à jour la question pour inclure des étiquettes contenant des espaces. Pouvez-vous me montrer comment cela fonctionnera pour inclure la mise à jour? J'adore la promenade.


Donc dans ce cas, le même code fonctionnera mais il comptera également les espaces. Voulez-vous sauter des espaces ou c'est ok? Je vous remercie.