簡體   English   中英

有什么方法可以使用 underscore.js 重命名 js object 鍵

[英]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);

來自https://www.geeksforgeeks.org/lodash-_-renamekeys-method/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM