2017-09-02 91 views
0

我有一個像下面的結構;Javascript從其他值獲取多維數組對象的值

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', 
     }, 
    } 

}; 

我想通過過濾它們的'屬性'值來獲取user-x元素的所有'value'條目。

例如,

我想根據他們的'權威'屬性過濾所有用戶的名字(不管在哪個設備和哪些用戶ID),並獲得'John Doe','Bill Doe','Jack Doe','Marry Doe'(作爲一個數組),如果我想篩選'author1 '權威',這樣我就可以得到哪些用戶在任何設備上擁有'author1'權限。

我檢查了很多地方(包括StackOverflow),但大多數例子都限於二維對象數組,變量是特定的或對象是基於整數(如[0] => Array)。

但在這個例子中,'device-x''user-x'項是不確定的(所以我不能說他們的價值觀是這些),但'name''authority'鍵是某些(由系統分配)和這些變量的數量可以改變(CRUD操作)。

謝謝你。

UPDATE:由於我的假設錯誤(我認爲如果我編寫不同的用戶x部分,人們認爲這些值不遵循任何規則)問題並不清楚。所以我編寫了代碼。 最後:'name'和'authority'鍵值對的所有者是用戶名,它們是用戶定義的。因此,所有設備對象都有id,模板,未知用戶字段,但所有未知用戶字段都必須具有「名稱」和「權限」鍵值對。

+0

這裏是你的代碼? –

+0

我想用這個:https://stackoverflow.com/questions/2722159/javascript-how-to-filter-object-array-based-on-attributes,但不能成功呢。 因爲,雖然引用的QA基於二維數組,但我無法實現子變量。 – Alper

回答

1

使用reduce & filter & map

更新:我添加了一個isLikeUserObj功能probs爲name & authority領域。

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)

+0

感謝您的回答,請您檢查問題更新 – Alper

+0

設備對象是否會包含id,'template','unknown-user-field'? – felixmosh

+0

是的,確切地說。但所有未知用戶字段必須具有「名稱」和「權限」鍵值對。 – Alper

0

您可以使用for-in循環遍歷一個對象。以下方法可以實現你的需求

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) 
+0

感謝您的回答,請您檢查問題更新 – Alper