lodash:配列をオブジェクトにマッピング


92

これを実行するための組み込みのlodash関数はありますか?

var params = [
    { name: 'foo', input: 'bar' },
    { name: 'baz', input: 'zle' }
];

そしてこれを出力します:

var output = {
    foo: 'bar',
    baz: 'zle'
};

今私はただ使っていArray.prototype.reduce()ます:

function toHash(array, keyName, valueName) {
    return array.reduce(function(dictionary, next) {
        dictionary[next[keyName]] = next[valueName];
        return dictionary;
    }, {});
}

toHash(params, 'name', 'input');

lodashのショートカットがあるかどうか疑問に思います。

回答:


138

lodash4.17.2の別の方法

_.chain(params)
    .keyBy('name')
    .mapValues('input')
    .value();

または

_.mapValues(_.keyBy(params, 'name'), 'input')

またはと _.reduce

_.reduce(
    params,
    (acc, { name, input }) => ({ ...acc, [name]: input }),
    {}
)

@Akrikosは_.keyBy配列全体をオブジェクトに変換しますが、問題は主に、配列内の各オブジェクトから1つのアイテムをキーとして、他の1つのアイテムを値として持つことです。場合_.keyByに使用され、その後、すべての値がオブジェクトになります。
Mustafa EhsanAlokozay19年

ありがとう@MustafaEhsanAlokozayそうです、その答えは正確に正しいことをしていません。役に立たないのでコメントを削除します。それはあなたのコメントを奇妙に見えるかもしれませんが、私の間違ったコメントがもう残っているよりはましです。
Akrikos

55

配列をオブジェクトに簡単に変換するには、_。keyByを使用する必要があります。

ここのドキュメント

以下の使用例:

var params = [
    { name: 'foo', input: 'bar' },
    { name: 'baz', input: 'zle' }
];
console.log(_.keyBy(params, 'name'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

必要に応じて、_。keyByを使用する前に配列を操作するか、_。keyByを使用した後にオブジェクトを操作して、正確な目的の結果を得ることができます。


2
stasovlasが最も投票した回答を理解するには、まずこれを見てください。
ローマンスージー2018

5
これはクールな答えですが、質問には答えませ。値はオブジェクトではなく文字列である必要があります。
DemPilafian19年

34

うん、それはここにある、を使用して_.reduce

var params = [
    { name: 'foo', input: 'bar' },
    { name: 'baz', input: 'zle' }
];

_.reduce(params , function(obj,param) {
 obj[param.name] = param.input
 return obj;
}, {});

さらにreduce()、別のユースケースで急降下します。それを行うスマートな方法!
ダン

誰かがこれのタイプスクリプトバージョンを手に入れましたか?
mr.bjerre

現実は、reduceはリストと同型であるため、reduce / injectを使用して文字通り任意の反復アクションを実装できるという数学的に真実です。ただし、その柔軟性には読みやすさの代償が伴います。_.reduce実行しようとしていることを正確に表現していない限り、使用しないでください。それ以外の場合は、コードの要点が大幅にわかりにくくなります。私は個人的に_.zipObject@djechlinによる解決策を好みます-それが失敗した場合、_.keyBy/_.mapValuesアプローチ。
ロバートフィッシャー

16

これはObject.assignの仕事のようです。

const output = Object.assign({}, ...params.map(p => ({[p.name]: p.input})));

OPと同様の関数としてラップするように編集すると、次のようになります。

const toHash = (array, keyName, valueName) => 
    Object.assign({}, ...array.map(o => ({[o[keyName]]: o[valueName]})));

(ベン・スチュワードに感謝します、良い考えです...)


たぶんそれを親関数でラップして、OPが持っていたように、ユーザーがそれらを渡すことによってどのキーが使用されるかを決定できるようにします。
ベンスチュワード


10

これはおそらくあなたが望むよりも冗長ですが、実際のコードが含まれる可能性があるため、少し複雑な操作を求めています(ホラー)。

私の推奨事項は、zipObjectかなり論理的です。

_.zipObject(_.map(params, 'name'), _.map(params, 'input'));

別のオプション、よりハッキー、使用fromPairs

_.fromPairs(_.map(params, function(val) { return [val['name'], val['input']));

匿名関数はハッキングを示しています-JSがオブジェクトの反復で要素の順序を保証する.values()とは思わないので、calllingはそうしません。


の使用についてハッキーなことは何も見当たりませんしfromPairs、電話をかけてもvalues()実際にはうまくいきません。少なくとも読みやすさの観点から。
x-yuri 2017

6

lodashの別の方法

ペアを作成してから、オブジェクトを作成するか、ES6 Map簡単に作成します

_(params).map(v=>[v.name, v.input]).fromPairs().value()

または

_.fromPairs(params.map(v=>[v.name, v.input]))

これが実際の例です


1
このソリューションの良い部分は、プレーンESでも実行可能であることです。Object.fromEntries(params.map(v => [v.name, v.input]))
fregante20年

@fregante、クロム73+のみcaniuse.com/?search=fromEntries
d9k

6

また、次のようなlodash関数を使用せずに解決することもできます。

let paramsVal = [
    { name: 'foo', input: 'bar' },
    { name: 'baz', input: 'zle' }
];
let output = {};

paramsVal.forEach(({name, input})=>{
  output[name] = input;
})


console.log(output);

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.