简体   繁体   中英

Javascript get values from multidimensional array object by other values

I have a structure like below;

var devices = {
    'device-1' : {
      'id' :'device1',
      'template' :'template-1',
      'user-1' :{
        'name' : 'John Doe',
        'authority' : 'author1',
      },
      'admin-1' :{
        'name' : 'Bob Doe',
        'authority' : 'author2',
      },
      'user-35' :{
        'name' : 'Bill Doe',
        'authority' : 'author1',
      },
      'author-42' :{
        'name' : 'Jack Doe',
        'authority' : 'author1|author3',
      }
  },
    'device-2' : {
      'id' :'device2',
      'template' :'template-2',
      'some-27' :{
        'name' : 'John Doe',
        'authority' : 'author1',
      },
      'other-42' :{
        'name' : 'Jack Doe',
        'authority' : 'author2',
      }
  },
    'device-7' : {
      'id' :'device7',
      'template' :'template-1',
      'user-2' :{
        'name' : 'Samantha Doe',
        'authority' : 'author2',
      }
      'admin-40' :{
        'name' : 'Marry Doe',
        'authority' : 'author1',
      },
    }

};

and I would like to get all 'value' entries of user-x elements by filtering their 'property' values.

Eg.

I would like filter all 'name's of users (no matter in which device and what are those user-ids) based on their 'authority' property and get 'John Doe','Bill Doe','Jack Doe','Marry Doe' (as an array) if I would like filter for 'author1' 'authority' so I can get which users have 'author1' authorities on any devices.

I've checked many places (including StackOverflow) but most of the examples are limited to two-dimensional object arrays, variables were specific or objects were based on an integer (like [0] => Array).

But in this example, 'device-x' and 'user-x' entries are uncertain (so I cannot say their values are these) but 'name' and 'authority' keys are certain (assign by the system) and the count of these variables can be varied (crud operations).

Thanks right now.

UPDATE : Because of my assumption error (I thought that if I write user-x parts different that each other, people think that these values are not follow any rule) question was not clear. So I edited in code. Finally : owners of 'name' and 'authority' key-value pairs are user names and they are user defined.

So, all device objects will have id, template, unknown-user-field, but all unknown-user-fields must have 'name' and 'authority' key-value pairs.

You can use for-in loop to traverse an object. Following ways could achieve your need

const result = []

for (let i in devices) {
  for (let j in devices[i]) {
    if (/user-\d+/.test(j)) {
      if (devices[i][j].authority.split('|').indexOf('author1') !== -1) {
        result.push(devices[i][j].name)
      }
    }
  }
}

console.log(result)

Using reduce & filter & map .

Updated : I've added a isLikeUserObj function that probs for name & authority fields.

 const devices = { 'device-1': { 'id': 'device1', 'template': 'template-1', 'user-1': { 'name': 'John Doe', 'authority': 'author1', }, 'admin-1': { 'name': 'Bob Doe', 'authority': 'author2', }, 'user-35': { 'name': 'Bill Doe', 'authority': 'author1', }, 'author-42': { 'name': 'Jack Doe', 'authority': 'author1|author3', } }, 'device-2': { 'id': 'device2', 'template': 'template-2', 'some-27': { 'name': 'John Doe', 'authority': 'author1', }, 'other-42': { 'name': 'Jack Doe', 'authority': 'author2', } }, 'device-7': { 'id': 'device7', 'template': 'template-1', 'user-2': { 'name': 'Samantha Doe', 'authority': 'author2', }, 'admin-40': { 'name': 'Marry Doe', 'authority': 'author1', }, } }; const result = getUserByAuthority('author3'); function getUserByAuthority(requiredAuth) { return Object.keys(devices).reduce((result, deviceKey) => { const users = Object.keys(devices[deviceKey]) .filter((key) => isUserLikeObj(devices[deviceKey][key])) .map(userKey => devices[deviceKey][userKey]) .filter((user) => user.authority.split('|').indexOf(requiredAuth) > -1) .map((user) => user.name) return result.concat(users); }, []) } function isUserLikeObj(value) { return typeof value === 'object' && value.hasOwnProperty('name') && value.hasOwnProperty('authority') } console.log(result) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM