[英]Is there any way to rename js object keys using underscore.js
我需要將 js object 轉換為另一個 object 以傳遞到服務器帖子,例如,鍵的名稱不同
var a = {
name : "Foo",
amount: 55,
reported : false,
...
<snip/>
...
date : "10/01/2001"
}
需要變成
a = {
id : "Foo",
total : 55,
updated: false,
...
<snip/>
...
issued : "10/01/2001"
}
我有可用於映射所有鍵的查找對象
var serverKeyMap = {
name : "id",
amount : "total",
reported : "updated",
...
date : "issue"
}
underscore.js 中是否有可用的 function 或 jQuery 我可以使用它來執行此功能?
謝謝
我知道您沒有提到lodash並且答案已經解決了問題,但其他人可能會利用替代方案。
正如評論中提到的@CookieMonster,您可以使用_.mapKeys
執行此_.mapKeys
:
_.mapKeys(a, function(value, key) {
return serverKeyMap[key];
});
和小提琴: http : //jsfiddle.net/cwkwtgr3/
與@pimvdb 類似,您也可以使用_.reduce
:
_.reduce(a, function(result, value, key) {
key = map[key] || key;
result[key] = value;
return result;
}, {});
小提琴: http : //jsfiddle.net/T9Lnr/39/
據我所知,這兩個庫中的任何一個都沒有內置函數。 不過,您可以相當容易地制作自己的: http : //jsfiddle.net/T9Lnr/1/ 。
var b = {};
_.each(a, function(value, key) {
key = map[key] || key;
b[key] = value;
});
您可以使用標准 JavaScript 將值復制到新屬性,並使用omit刪除原始屬性,如下所示:
a.id = a.name;
a.total = a.amount;
a.updated = a.reported;
a = _.omit(a, 'name', 'amount', 'reported');
// key_map: {old_name1: new_name1, ... }
function rename_keys(object, key_map, is_picked=false){
keys = _.keys(key_map);
new_keys = _.values(key_map);
picked = _.pick(object, keys);
renamed = _.object(new_keys, _.values(picked));
if(is_picked) return renamed;
return _.chain(object).omit(keys).extend(renamed).value();
}
這可能比上述答案慢。
我有一個轉換運算符,只想將它應用於所有鍵。 我分叉了 pimvdb 的小提琴來產生一個簡單的例子。 在這種情況下,它會將密鑰大寫。 並且它動態構建鍵映射,我需要它來確保工作(感謝 JSFiddle)。
這是更改后的代碼:
var keymap = {};
_.each(a, function(value, key) {
var oldkey = key;
key = capitalize(key);
keymap[oldkey] = key;
});
_.each(a, function(value, key) {
key = keymap[key] || key;
b[key] = value;
});
小提琴: http : //jsfiddle.net/mr23/VdNjf/
這里已經解決了https://stackoverflow.com/a/30940370/1360897
var keyMapping = {'PropertyA': 'propertyA', ..., 'PropertyF': 'propertyNEW'}
以及新舊值的映射,像這樣
var valueMapping = {'Y': true, 'F': false}
然后使用_.map和_.transform,就可以對對象進行變換,像這樣
var result = _.map(allItems, function(currentObject) {
return _.transform(currentObject, function(result, value, key) {
if (key === 'PropertyF' || key === 'PropertyG') {
value = valueMapping(value);
}
result[keyMapping[key]] = value;
});
});
不,兩個庫中都沒有顯式重命名鍵的函數。 您的方法也是最快的(請參閱jsperf 測試。)如果可能,您最好的選擇是重構客戶端或服務器端代碼,以便對象相同。
你為什么不使用這個簡單的java腳本? 任何鍵值對的值應該是字符串/數字/布爾值。
<script type="text/javascript">
var serverKeyMap = {
name : "id",
amount : "total",
reported : "updated"
};
var a = {
name : "Foo",
amount: 55,
reported : false
};
var b={}; // b is object where you will get your output
for(i in serverKeyMap) b[serverKeyMap[i]]=a[i];
console.log(b); // It gives what you need.
</script>
正如 user2387823上面所說的 👆 使用omit是一個不錯的選擇。 例如你可以寫這樣的東西
function updateObjKey(obj, currentKey, newKey) {
var keyValue = obj[currentKey];
obj = _.omit(obj, [currentKey]);
obj[newKey] = keyValue;
return obj;
}
這個 ES2015/2017 版本🧙♂️
function objectMap(source,keyMap) { return Object.entries(keyMap).reduce((o,[key , newKey]) => { o[newKey]=source[key] return o;},{}) } const obj = { name : "Foo", amount: 55, reported : false, date : "10/01/2001" } const serverKeyMap = { name : "id", amount : "total", reported : "updated", date : "issue" } const result = objectMap(obj,serverKeyMap); console.log('🎬 =>' , result);
[Object.entries][1]
是 es2017 feture 將對象鍵和值作為數組返回[["name", "id"],["amount", "total"],...]
你真的不需要下划線/lodash ......現在無論如何(我意識到這個問題是 9 年前提出的,但這個問題(仍然)在搜索結果中排名很高,我今天遇到了它 :-) )
這是我喜歡的另一個簡單的 ES2015/2017 版本,靈感來自@malbarmavi 的答案(那里可能有很多其他普通的 JS 函數,但我在簡短的搜索中沒有遇到任何其他函數):
// A general key transform method. Pass it a function that accepts the old key and returns
// the new key.
//
// @example
// obj = transformKeys(obj, (key) => (
// key.replace(/\b(big)\b/g, 'little')
// ))
export function transformKeys(source, f) {
return Object.entries(source).reduce((o, [key, value]) => {
o[f(key) || key] = value
return o
}, {})
}
// Provide an object that maps from old key to new key
export function rekeyObject(source, keyMap) {
transformKeys(source, key => keyMap[key])
}
使用下划線omit
和展開運算符。
a = _.omit({
...a,
id: a.name,
total: a.amount,
updated: a.reported,
}, ['name', 'amount', 'reported']);
展開運算符下面的鍵分配加載新鍵並省略舊鍵。
您可以創建新的自定義函數:
lodash.rename = function(obj, keys, newKeys) {
keys.map((key, index) => {
if(lodash.includes(lodash.keys(obj), key)) {
obj[newKeys[index]] = lodash.clone(obj[key], true);
delete obj[key];
}
});
return obj;
};
否則,如果您只想編輯一個 keyName:
lodash.rename = function(obj, key, newKey) {
if(lodash.includes(lodash.keys(obj), key)) {
obj[newKeys[index]] = lodash.clone(obj[key], true);
delete obj[key];
}
return obj;
};
我參考了 lodash 文檔並找到了mapKeys
https://lodash.com/docs/4.17.15#mapKeys
_.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
return key + value;
});
// => { 'a1': 1, 'b2': 2 }
這完美地重命名鍵並返回一個包含修改后的所需對象的對象
使用 lodash
var obj = _.renameKeys( { 1 : "Geeks",
2 : "Computer_Science_Portal" },
{ 1 : "g", 2 : "c" });
所以在你的情況下,你想將 serverKeyMap 應用到 object a 上:
var obj = _.renameKeys(a, serverKeyMap);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.