web-dev-qa-db-ja.com

underscore.jsを使用して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で使用可能な、この機能を実行する関数はありますか?

ありがとう

59
claya

私の知る限り、これらの2つのライブラリのいずれにも機能は組み込まれていません。ただし、自分で簡単に作成できます。 http://jsfiddle.net/T9Lnr/1/

var b = {};

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

lodash に言及していないことは知っていますが、答えはすでに問題を解決していますが、他の誰かが代替案を利用するかもしれません。

@CookieMonsterがコメントで言及したように、これは _.mapKeys

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

そしてフィドル: http://jsfiddle.net/cwkwtgr3/

64
Samir Aguiar

@pimvdbと同様に、_.reduce

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

フィドル: http://jsfiddle.net/T9Lnr/39/

40
dule

次のように、標準JavaScriptを使用して新しいプロパティに値をコピーし、omitを使用して元のプロパティを削除できます。

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

ここで解決されました 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;
    });
});
3
aemonge

変換演算子があり、すべてのキーに適用したいだけです。 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/

2
mr23

どちらのライブラリにも、明示的にキーの名前を変更する機能はありません。また、メソッドは最速です( jsperf tests を参照してください)。可能な場合は、オブジェクトが同じになるようにクライアント側またはサーバー側のコードをリファクタリングすることをお勧めします。

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

これは上記の回答よりも遅い場合があります。

2
Zin Kanzaki

なぜこの単純なJava script?.

<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>
2
Umesh Patil

ユーザー2387823が言っていたように 上記 ???? omitを使用するのは素晴らしいオプションです。たとえば、次のように書くことができます

function updateObjKey(obj, currentKey, newKey) {
    var keyValue = obj[currentKey];
    obj = _.omit(obj, [currentKey]);
    obj[newKey] = keyValue;
    return obj;
  }
1
Brandon Howard

この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"],...]
0
malbarmawi