[英]Javascript - map value to keys (reverse object mapping)
我想反轉對象的映射(可能有重復的值)。 示例:
const city2country = {
'Amsterdam': 'Netherlands',
'Rotterdam': 'Netherlands',
'Paris': 'France'
};
reverseMapping(city2country)
應該輸出:
{
'Netherlands': ['Amsterdam', 'Rotterdam'],
'France': ['Paris']
}
我想出了以下幼稚的解決方案:
const reverseMapping = (obj) => {
const reversed = {};
Object.keys(obj).forEach((key) => {
reversed[obj[key]] = reversed[obj[key]] || [];
reversed[obj[key]].push(key);
});
return reversed;
};
但我很確定有一種更簡潔、更短的方法,最好是原型,這樣我就可以簡單地做:
const country2cities = city2country.reverse();
您可以使用Object.assign
,同時尊重給定的插入值數組。
const city2country = { Amsterdam: 'Netherlands', Rotterdam: 'Netherlands', Paris: 'France' }; const reverseMapping = o => Object.keys(o).reduce((r, k) => Object.assign(r, { [o[k]]: (r[o[k]] || []).concat(k) }), {}) console.log(reverseMapping(city2country));
JavaScript 中沒有這樣的內置函數。 您的代碼看起來不錯,但考慮到這里有很多可能出錯的邊緣情況,我建議使用invertBy
的 invertBy ,它完全符合您的描述。
var object = { 'a': 1, 'b': 2, 'c': 1 }; _.invertBy(object); // => { '1': ['a', 'c'], '2': ['b'] }
您可以使用這樣的東西來首先獲取重復項:
function removeDuplicates(arr, key) {
if (!(arr instanceof Array) || key && typeof key !== 'string') {
return false;
}
if (key && typeof key === 'string') {
return arr.filter((obj, index, arr) => {
return arr.map(mapObj => mapObj[key]).indexOf(obj[key]) === index;
});
} else {
return arr.filter(function(item, index, arr) {
return arr.indexOf(item) == index;
});
}
}
然后使用它使其反轉:
function reverseMapping(obj){
var ret = {};
for(var key in obj){
ret[obj[key]] = key;
}
return ret;
}
您可以使用 reduce 來保存聲明行reduce 。
在使用Array.concat
之前,濫用&&
檢查是否首先定義了map[object[key]]
。
它更短,但它更簡單嗎? 可能不是,但有點樂趣;)
const reverseMapping = (object) =>
Object.keys(object).reduce((map, key) => {
map[object[key]] = map[object[key]] && map[object[key]].concat(key) || [key]
return map;
}, {});
您可以嘗試從當前對象獲取一組值和一組鍵,並設置一個新對象來保存結果。 然后,當您遍歷值數組時 -
Netherlands
,你創建一個新數組,獲取已經存在的值(例如: Rotterdam
),並將這個值和新值( Amsterdam
)添加到數組中,並設置這個數組作為Netherlands
鍵的新值。France
是鍵, Paris
是值。代碼 -
const city2country = { 'Amsterdam': 'Netherlands', 'Rotterdam': 'Netherlands', 'Paris': 'France', }; function reverseMapping(obj) { let values = Object.values(obj); let keys = Object.keys(obj); let result = {} values.forEach((value, index) => { if(!result.hasOwnProperty(value)) { // create new entry result[value] = keys[index]; } else { // duplicate property, create array let temp = []; // get first value temp.push(result[value]); // add second value temp.push(keys[index]); // set value result[value] = temp; } }); console.log(result); return result; } reverseMapping(city2country)
這里的好處是 - 它會根據您當前對象的結構進行調整 - Netherlands
是重復值,在新對象中獲得一個數組作為它的值,而France
獲得一個字符串值Paris
作為它的屬性。 當然,改變這個應該很容易。
注 - 舊瀏覽器可能不支持Object.values() 。
@Nina Scholz 的回答非常適合這個確切的問題。 :thumbsup:
但是,如果您不需要保留荷蘭鍵的兩個值( "Netherlands": ["Amsterdam", "Rotterdam"]
),那么這會更短更容易閱讀:
const city2country = { Amsterdam: 'Netherlands', Rotterdam: 'Netherlands', Paris: 'France' };
console.log(
Object.entries(city2country).reduce((obj, item) => (obj[item[1]] = item[0]) && obj, {})
);
// outputs `{Netherlands: "Rotterdam", France: "Paris"}`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.