0

I currently have a Object which looks like so:

{
    "Best Fare Description": {
        "text": {
            "value": "One",
            "type": "TEXT"
        }
    },
    "Brand ID": {
        "text": {
            "value": "test",
            "type": "TEXT"
        }
    },
    "Program ID": {
        "text": {
            "value": "test",
            "type": "TEXT"
        }
    },
    "Max Elapse Time": {
        "integer": {
            "value": 4,
            "type": "INTEGER"
        }
    },
    "Max Number of Connections": {
        "integer": {
            "value": 5,
            "type": "INTEGER"
        }
    }
}

I am trying to iterate through the object and create an array of only the values. So for this object I would return an array of

["One","test","test",4,5]

What I've Tried:

data being the object

      const tempList = [];

      for (var key in data) {
        for (var key2 in data[key]) {
            for (var key3 in data[key][key2]) {
                tempList.push(key3['value'])
                }
            }
        }

However it seems like I am not doing something correct, as I get undefined or errors when I push into the array. Is there an easier/More Efficient way to accomplish this? Any help would be appreciated!

5 Answers 5

2

Because of the dynamic keys, you could take the values and map the last item.

var data = { "Best Fare Description": { text: { value: "One", type: "TEXT" } }, "Brand ID": { text: { value: "test", type: "TEXT" } }, "Program ID": { text: { value: "test", type: "TEXT" } }, "Max Elapse Time": { integer: { value: 4, type: "INTEGER" } }, "Max Number of Connections": { integer: { value: 5, type: "INTEGER" } } },
    result = Object.values(data).map(o => Object.values(o)[0].value);

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

Sign up to request clarification or add additional context in comments.

Comments

1

The easiest thing is to loop over the Object.values of the two levels using map and reduce to build your array:

let obj = {"Best Fare Description": {"text": {"value": "One","type": "TEXT"}},"Brand ID": {"text": {"value": "test","type": "TEXT"}},"Program ID": {"text": {"value": "test","type": "TEXT"}},"Max Elapse Time": {"integer": {"value": 4,"type": "INTEGER"}},"Max Number of Connections": {"integer": {"value": 5,"type": "INTEGER"}}}

let arr = Object.values(obj).reduce((arr, item) => {
  arr.push(...Object.values(item).map(inner => inner.value))
  return arr
}, [])
console.log(arr)

Newer javascript engines will let you simplify a bit with flatMap:

let obj = {"Best Fare Description": {"text": {"value": "One","type": "TEXT"}},"Brand ID": {"text": {"value": "test","type": "TEXT"}},"Program ID": {"text": {"value": "test","type": "TEXT"}},"Max Elapse Time": {"integer": {"value": 4,"type": "INTEGER"}},"Max Number of Connections": {"integer": {"value": 5,"type": "INTEGER"}}}

let arr = Object.values(obj).flatMap(item => Object.values(item).map(inner => inner.value))
console.log(arr)

Comments

0

It seems you innermost object's structure stays the same. In that case, you could slightly change your existing code to do something like the following:

const tempList = [];
for (let key in data) {
  for (let key2 in data[key]) {
    tempList.push(data[key][key2].value);
  }
}

Comments

0

Here's a recursive function that will do what you need (it will work with any shape of object):

const findValues => obj => Object.keys(obj).reduce((acc,key)=>{
  if(key==='value'){
    acc.push(obj[key])
  }else if(typeof obj[key]==='object'){
    acc.push(findValues(obj[key]))
  }
  return acc.flat()
},[])

So if your object is:

const obj = {
    "Best Fare Description": {
        "text": {
            "value": "One",
            "type": "TEXT"
        }
    },
    "Brand ID": {
        "text": {
            "value": "test",
            "type": "TEXT"
        }
    },
    "Program ID": {
        "text": {
            "value": "test",
            "type": "TEXT"
        }
    },
    "Max Elapse Time": {
        "integer": {
            "value": 4,
            "type": "INTEGER"
        }
    },
    "Max Number of Connections": {
        "integer": {
            "value": 5,
            "type": "INTEGER"
        }
    }
}

You would call it like this:

findValues(obj) // ["One", "test", "test", 4, 5]

A more generic version:

const findValues = selector => obj => Object.keys(obj).reduce((acc,key)=>{
  debugger
  if(key===selector){
    acc.push(obj[key])
  }else if(typeof obj[key]==='object'){
    acc.push(findValues(selector)(obj[key]))
  }
  return acc.flat()
},[])

findValues('value')(obj) // ["One", "test", "test", 4, 5]

Codepen here: https://codepen.io/jenko3000/pen/yWWJxg

Comments

-1

You're saying tempList.push(key3['value']), but key3 is a string, not an array. You also don't need 3 loops, you only need 2.

let data = {
    "Best Fare Description": {
        "text": {
            "value": "One",
            "type": "TEXT"
        }
    },
    "Brand ID": {
        "text": {
            "value": "test",
            "type": "TEXT"
        }
    },
    "Program ID": {
        "text": {
            "value": "test",
            "type": "TEXT"
        }
    },
    "Max Elapse Time": {
        "integer": {
            "value": 4,
            "type": "INTEGER"
        }
    },
    "Max Number of Connections": {
        "integer": {
            "value": 5,
            "type": "INTEGER"
        }
    }
}

const tempList = [];

for (var key in data) {
  for (var key2 in data[key]) {
      if (data[key][key2]['value'])
        tempList.push(data[key][key2]['value'])
  }
}
  
  console.log(tempList);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.