lodash : 객체에 배열 매핑


90

이것을 수행하는 내장 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 지름길이 있는지 궁금합니다.

답변:


132

lodash 4.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전체 배열을 객체로 변환하지만 질문은 대부분 배열의 각 객체에서 하나의 항목을 키로, 다른 항목 하나를 값으로 갖는 것에 관한 것입니다. 경우에 _.keyBy사용되며, 모든 값은 객체가 될 것입니다.
Mustafa Ehsan Alokozay

감사합니다 @MustafaEhsanAlokozay 당신이 맞아요, 그 대답은 옳은 일을하지 않습니다. 도움이되지 않는 댓글을 삭제하겠습니다. 그것은 귀하의 의견을 이상하게 보일 수 있지만 잘못된 의견을 더 이상 유지하는 것보다 좋습니다.
Akrikos

53

배열을 객체로 쉽게 변환하려면 _.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가 가장 많이 투표 한 답변을 이해하려면 먼저 이것을보십시오.
Roman Susi

3
이것은 멋진 대답이지만 질문에 대한 대답 은 아닙니다 . 값은 객체가 아닌 문자열이어야합니다.
Dem Pilafian 19

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()다른 사용 사례가 등장합니다 . 똑똑한 방법!
Dan

누구든지 이것의 타이프 스크립트 버전을 가지고 있습니까?
mr.bjerre

현실은 reduce / inject를 사용하여 문자 그대로 모든 반복 작업을 구현할 수 있다는 것이 수학적으로 사실입니다. reduce는 목록과 동형이기 때문입니다. 그러나 이러한 유연성에는 가독성에 대한 대가가 따릅니다. _.reduce수행하려는 작업을 정확하게 표현 하지 않는 한 사용 하지 마십시오 . 다른 경우에는 코드의 요지를 상당히가립니다. 나는 개인적 _.zipObject으로 @djechlin 의 솔루션을 선호합니다 -실패, _.keyBy/ _.mapValues접근 방식.
Robert Fischer

15

이것은 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]})));

(Ben Steward에게 감사합니다, 좋은 생각 ...)


OP처럼 키를 전달하여 사용자가 어떤 키를 사용할 것인지 결정할 수 있도록 부모 함수로 감쌀 수도 있습니다.
Ben Steward


10

이것은 아마도 원하는 것보다 더 장황 할 수 있지만 약간 복잡한 작업을 요구하므로 실제 코드가 관련 될 수 있습니다 (공포).

내 추천 zipObject은 매우 논리적입니다.

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

또 다른 옵션은 더 해키, 사용 fromPairs:

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

익명 함수는 해킹을 보여줍니다. JS가 객체 반복에서 요소의 순서를 보장한다고 믿지 않으므로 callling은 수행하지 않습니다 .values().


나는을 사용하는 것에 대해 엉뚱한 것을 보지 못하며 실제로 fromPairs호출 values()하지 않을 것입니다. 적어도 가독성 관점에서.
x-yuri

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]))
fregante

@fregante, Chrome 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.