有没有办法使用underscore.js重命名js对象键

时间:2012-01-05 18:14:35

标签: javascript jquery underscore.js

我需要将一个js对象转换为另一个对象,以便传递到一个服务器帖子,其中键的名称不同,例如

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"
  }

我有查找obj可用于映射所有键

var serverKeyMap = {
    name : "id",
    amount : "total",
    reported : "updated",
     ...
    date : "issue"
    }

我可以使用underscore.js或jQuery中的函数来执行此功能吗?

感谢

14 个答案:

答案 0 :(得分:60)

我知道你没有提到lodash,答案已经解决了问题,但其他人可能会利用另一种选择。

正如评论中提到的@CookieMonster,您可以使用_.mapKeys执行此操作:

_.mapKeys(a, function(value, key) {
    return serverKeyMap[key];
});

小提琴:http://jsfiddle.net/cwkwtgr3/

答案 1 :(得分:40)

与@pimvdb类似,您也可以使用_.reduce

执行此操作
_.reduce(a, function(result, value, key) {
    key = map[key] || key;
    result[key] = value;
    return result;
}, {});

小提琴:http://jsfiddle.net/T9Lnr/39/

答案 2 :(得分:33)

据我所知,这两个库中没有内置任何功能。不过,您可以相当轻松地制作自己的作品:http://jsfiddle.net/T9Lnr/1/

var b = {};

_.each(a, function(value, key) {
    key = map[key] || key;
    b[key] = value;
});

答案 3 :(得分:11)

您可以使用标准JavaScript将值复制到新属性,并使用省略删除原始属性,如下所示:

a.id = a.name;
a.total = a.amount;
a.updated = a.reported;
a = _.omit(a, 'name', 'amount', 'reported');

答案 4 :(得分:2)

两个库中都没有显式重命名键的功能。您的方法也是最快的(参见jsperf tests。)如果可能,最好的办法是重构客户端或服务器端代码,以便对象相同。

答案 5 :(得分:2)

为什么不使用这个简单的java脚本?任何键:值对的值应为string / number / Boolean。

<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>

答案 6 :(得分:2)

我有一个转换运算符,只想将它应用于所有键。我把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/

答案 7 :(得分:2)

// 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();
}

这可能比上述答案慢。

答案 8 :(得分:1)

用户2387823使用省略above是一个不错的选择。例如,你可以写这样的东西

document.getElementById("show_test").innerHTML += '<div><a href="#" id="bt_' + item + '">click</a></div>';

答案 9 :(得分:1)

你真的不需要下划线/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])
}

答案 10 :(得分:0)

此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 feature将返回对象密钥,并且   值作为数组

[["name", "id"],["amount", "total"],...]

答案 11 :(得分:0)

使用下划线omit和传播运算符。

a = _.omit({
  ...a,
  id: a.name,
  total: a.amount,
  updated: a.reported,
}, ['name', 'amount', 'reported']);

spread运算符下方的键分配会加载新键,而忽略旧键。

答案 12 :(得分:0)

您可以创建新的自定义函数:

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;
};

答案 13 :(得分:0)

我参考了 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 }

这完美地重命名了键并返回一个包含修改后的所需对象的对象