객체 보존 키로 매핑


129

그만큼 mapunderscore.js 함수는 javascript 객체와 함께 호출 된 경우 객체 값에서 매핑 된 값의 배열을 반환합니다.

_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]

키를 보존하는 방법이 있습니까? 즉, 나는 반환하는 함수를 원한다

{one: 3, two: 6, three: 9}

나처럼, 새로운 객체를 반환하는 대신 실제 객체를 변경하는 함수와 같은 'mapValues'를 찾고 있다면이 간단한 솔루션을 확인하십시오. stackoverflow.com/questions/30894044/…
Michael Trouw

답변:


228

밑줄

밑줄은 _.mapObject값을 매핑하고 키를 유지 하는 기능 을 제공 합니다.

_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });

// => { one: 3, two: 6, three: 9 }

DEMO


Lodash

Lodash는 _.mapValues값을 매핑하고 키를 유지 하는 기능 을 제공 합니다.

_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });

// => { one: 3, two: 6, three: 9 }

DEMO


_.mapValues ​​함수를 밑줄로 가져 오려는 노력이있었습니다 : 관련 문제 , _.mapValues에 대한 풀 요청 . 나는 이것이 통과되기를 바랍니다 :)
raffomania

그것은 당신이 물건을 대상으로 만들고있는 것처럼 보입니까, 아니면 내 마음에서 벗어 났습니까?
jsh

@jsh이 경우, 배열의 배열 인을 _.map()반환 하고 다시 개체로 변환합니다. [['one', 3], ['two', 6], ['three', 9]]_.object()
Jezen Thomas

56

밑줄과 비슷한 유틸리티 라이브러리 인 lodash에서 필요한 기능을 찾을 수있었습니다.

http://lodash.com/docs#mapValues

_.mapValues(object, [callback=identity], [thisArg])

콜백을 통해 객체의 열거 가능한 각 속성을 실행하여 생성 된 객체 및 값과 동일한 키로 객체를 만듭니다. 콜백은 thisArg에 바인딩되며 세 개의 인수로 호출됩니다. (값, 키, 객체).


19

var mapped = _.reduce({ one: 1, two: 2, three: 3 }, function(obj, val, key) {
    obj[key] = val*3;
    return obj;
}, {});

console.log(mapped);
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


13

나는 이것이 오래되었다는 것을 알고 있지만 이제 Underscore에는 객체에 대한 새로운 맵이 있습니다.

_.mapObject(object, iteratee, [context]) 

물론 배열과 객체 모두에 대해 유연한지도를 만들 수 있습니다

_.fmap = function(arrayOrObject, fn, context){
    if(this.isArray(arrayOrObject))
      return _.map(arrayOrObject, fn, context);
    else
      return _.mapObject(arrayOrObject, fn, context);
}

5
lodash 사용자를위한 참고 사항 : jdalton 은이 변경으로 인해 underscore.js와의 호환성중단 하기로 결정했습니다 . lodash는 지원하지 않습니다 mapObject. mapValues대신 lodash의 방법을보십시오.
Mark Amery

13

일반 JS ( ES6 / ES2015 ) 에서이 버전은 어떻습니까?

let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));

jsbin

객체를 재귀 적으로 매핑하려면 (중첩 된 obj 매핑) 다음과 같이 수행 할 수 있습니다.

const mapObjRecursive = (obj) => {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === 'object') obj[key] = mapObjRecursive(obj[key]);
    else obj[key] = obj[key] * 3;
  });
  return obj;
};

jsbin

이후 ES7 / ES2016 당신이 사용할 수있는 Object.entries대신에 Object.keys이 같은 :

let newObj = Object.assign(...Object.entries(obj).map([k, v] => ({[k]: v * 3})));

5

나는 그것이 오랜 시간이라는 것을 알고 있지만 폴드 (일명 js로 줄임)를 통한 가장 확실한 해결책이 누락되었습니다. 완전성을 위해 여기에 남겨 두겠습니다.

function mapO(f, o) {
  return Object.keys(o).reduce((acc, key) => {
    acc[key] = f(o[key])
    return acc
  }, {})
}

Lodash 라이브러리를 사용하는 것은 괜찮지 만 프로그래머는 이러한 종류의 라이브러리를 사용하고 있으며 바닐라 JS 에서이 작업을 수행하는 방법을 모릅니다. 답변 해 주셔서 감사합니다.
cyonder

3

_.map 은 객체가 아닌 배열을 반환합니다.

객체를 원한다면 each; 과 같은 다른 기능을 사용하는 것이 좋습니다 . 정말로 맵을 사용하려면 다음과 같이 할 수 있습니다.

Object.keys(object).map(function(value, index) {
   object[value] *= 3;
})

그러나 map결과적으로 배열을 가지고 무언가를 만들 것으로 기대할 때 혼란 스럽 습니다.


underscore.js에서 이것을 시도하는 것이 자연스럽지 않다는 문서를 읽는 느낌이 들었습니다. 내 유스 케이스가 매우 자연 스럽다고 생각합니다. 왜 지원하지 않습니까?
xuanji

map배열을 생성하는 입력을 출력으로 변경하는 데 사용되는 이유 중 하나는 아마도 작성 _.object하고 _.map@GG로 할 수 있기 때문입니다. 글을 썼지 만,이 시점에서 그것은 맛의 문제입니다.
Alberto Zaccagni

3

나는 당신이 직접 구현하기에 충분히 쉬운 mapValues 함수 (객체의 값에 함수를 매핑하기 위해) 를 원한다고 생각합니다 .

mapValues = function(obj, f) {
  var k, result, v;
  result = {};
  for (k in obj) {
    v = obj[k];
    result[k] = f(v);
  }
  return result;
};

2
const mapObject = (obj = {}, mapper) =>
  Object.entries(obj).reduce(
    (acc, [key, val]) => ({ ...acc, [key]: mapper(val) }),
    {},
  );

이 답변을 직접 추가하려고했습니다. 다행 이네!
빌 크리스 웰

0

밑줄 맵 버그 의 혼합 수정 : P

_.mixin({ 
    mapobj : function( obj, iteratee, context ) {
        if (obj == null) return [];
        iteratee = _.iteratee(iteratee, context);
        var keys = obj.length !== +obj.length && _.keys(obj),
            length = (keys || obj).length,
            results = {},
            currentKey;
        for (var index = 0; index < length; index++) {
          currentKey = keys ? keys[index] : index;
          results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
        }
        if ( _.isObject( obj ) ) {
            return _.object( results ) ;
        } 
        return results;
    }
}); 

올바른 키를 유지하고 객체로 반환하는 간단한 해결 방법이 게스트를 사용하여 bugy _.map 함수를 재정의 할 수있는 것과 동일한 방식으로 여전히 사용됩니다.

또는 내가 믹스 인으로 사용한 것처럼

_.mapobj ( options , function( val, key, list ) 

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.