0

Desired State

I'm trying to return an object from an array that matches a specific value and I'm running into some issues because the array contains objects nested within another object. I want to return the entire object but the value I need to search by is inside the nested object.

For example, I'm trying to return this entire object, based on the value of the key:value pair "name": "Kills"

 {
    "metadata": {
        "key": "kills",
        "name": "Kills",
        "isReversed": false
    },
    "value": 1364,
    "displayValue": "1,364"
}

Array Format

let stats = [
            {
                "metadata": {
                    "key": "kills",
                    "name": "Kills",
                    "isReversed": false
                },
                "value": 1364,
                "displayValue": "1,364"
            },
            {
                "metadata": {
                    "key": "score",
                    "name": "Score",
                    "isReversed": false
                },
                "value": 413743,
                "displayValue": "413,743"
            },
            {
                "metadata": {
                    "key": "matchesPlayed",
                    "name": "Matches Played",
                    "isReversed": false
                },
                "value": 2160,
                "displayValue": "2,160"
            }

        ]

Current Code that isn't working

I'm not set on using code of this structure, any solution that works is great for me but I need it to be a function I can reuse.

function getStatsFields(value, statsSegment){
  console.log('getStatsFields ran', statsSegment.stats[0].metadata.name);

  console.log('statsSegment.stats.length', statsSegment.stats.length);
  var filteredStats = []
  for(var i=0; i < statsSegment.stats.length; ++i){
    const killsKey = Object.keys(statsSegment.stats[i].metadata.name)
    console.log('killsKey', killsKey);
    filteredStats = statsSegment.stats.filter(val => val[killsKey] === value)
    console.log('filteredStats before if', filteredStats);
    if(filteredStats.length){
      console.log('filteredStats[i]', filteredStats[i]);

      return filteredStats[i];
    }
  }

}

Any help would be greatly appreciated!

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
bzlight
  • 1,066
  • 4
  • 17
  • 43
  • 1
    Possible duplicate of [How to determine if Javascript array contains an object with an attribute that equals a given value?](https://stackoverflow.com/questions/8217419/how-to-determine-if-javascript-array-contains-an-object-with-an-attribute-that-e) – Heretic Monkey Feb 28 '19 at 18:18
  • 1
    I think its a little different because of my array contains nested objects. I also took a look at the solution for the link you posted and Kamil's below is much less code. Thanks though! – bzlight Feb 28 '19 at 21:22
  • Nested object uses the same code, just adding an extra dot, and [there are answers in that question](https://stackoverflow.com/a/41916199/215552) that use the same amount of code. – Heretic Monkey Feb 28 '19 at 21:57
  • @Heretic that makes sense but this is still one line of code and therefore I think its much more concise – bzlight Feb 28 '19 at 23:31

2 Answers2

2

Try

stats.find(x=> x.metadata.name=="Kills");

let stats= [
            {
                "metadata": {
                    "key": "kills",
                    "name": "Kills",
                    "isReversed": false
                },
                "value": 1364,
                "displayValue": "1,364"
            },
            {
                "metadata": {
                    "key": "score",
                    "name": "Score",
                    "isReversed": false
                },
                "value": 413743,
                "displayValue": "413,743"
            },
            {
                "metadata": {
                    "key": "matchesPlayed",
                    "name": "Matches Played",
                    "isReversed": false
                },
                "value": 2160,
                "displayValue": "2,160"
            }

        ]
        
  let r= stats.find(x=> x.metadata.name=="Kills");
  console.log(r);
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
0

If you are looking for a method to filter by a metadata (key, value) pair, maybe the next could help you:

const stats = [
  {
    "metadata": {
      "key": "kills",
      "name": "Kills",
      "isReversed": false
    },
    "value": 1364,
    "displayValue": "1,364"
  },
  {
    "metadata": {
      "key": "score",
      "name": "Score",
      "isReversed": false
    },
    "value": 413743,
    "displayValue": "413,743"
  },
  {
    "metadata": {
      "key": "matchesPlayed",
      "name": "Matches Played",
      "isReversed": false
    },
    "value": 2160,
    "displayValue": "2,160"
  }
];

const filterByMetaKeyVal = (arr, metakey, v) =>
{
    return arr.filter(({metadata}) => metadata[metakey] === v);
}

console.log(
  "Filter by [name, Kills]:",
  filterByMetaKeyVal(stats, "name", "Kills")
);
console.log(
  "Filter by [key, matchesPlayed]:",
  filterByMetaKeyVal(stats, "key", "matchesPlayed")
);
console.log(
  "Filter by [isReversed, true]:",
  filterByMetaKeyVal(stats, "isReversed", true)
);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Shidersz
  • 16,846
  • 2
  • 23
  • 48