etc./StackOverFlow

객체에 대한 map 함수(배열 대신)

청렴결백한 만능 재주꾼 2022. 7. 6. 02:42
반응형

질문자 :Randomblue


나는 개체가 있습니다 :

 myObject = { 'a': 1, 'b': 2, 'c': 3 }

다음과 같이 사용되는 Array.prototype.map 과 유사한 기본 메서드를 찾고 있습니다.

 newObject = myObject.map(function (value, label) { return value * value; }); // newObject is now { 'a': 1, 'b': 4, 'c': 9 }

JavaScript에 객체에 대한 map (Node.JS에 이것을 원하므로 브라우저 간 문제는 신경 쓰지 않습니다.)



Object map 은 없지만 다음은 어떻습니까?

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }; Object.keys(myObject).map(function(key, index) { myObject[key] *= 2; }); console.log(myObject); // => { 'a': 2, 'b': 4, 'c': 6 }

for ... in 사용하여 객체를 쉽게 반복할 수 있습니다.

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }; for (var key in myObject) { if (myObject.hasOwnProperty(key)) { myObject[key] *= 2; } } console.log(myObject); // { 'a': 2, 'b': 4, 'c': 6 }

업데이트

많은 사람들이 이전 메서드가 새 개체를 반환하지 않고 개체 자체에 대해 작동한다고 언급하고 있습니다. 그 문제에 대해 새 객체를 반환하고 원래 객체를 그대로 두는 다른 솔루션을 추가하고 싶었습니다.

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }; // returns a new object with the values at each key mapped using mapFn(value) function objectMap(object, mapFn) { return Object.keys(object).reduce(function(result, key) { result[key] = mapFn(object[key]) return result }, {}) } var newObject = objectMap(myObject, function(value) { return value * 2 }) console.log(newObject); // => { 'a': 2, 'b': 4, 'c': 6 } console.log(myObject); // => { 'a': 1, 'b': 2, 'c': 3 }

Array.prototype.reduce 는 이전 값을 현재 값과 어느 정도 병합하여 배열을 단일 값으로 줄입니다. 체인은 빈 객체 {} 의해 초기화됩니다. myObject 의 새 키가 값의 두 배와 함께 추가됩니다.

업데이트

objectMap 을 표현하는 더 우아한 방법이 있습니다.

 const objectMap = (obj, fn) => Object.fromEntries( Object.entries(obj).map( ([k, v], i) => [k, fn(v, k, i)] ) ) const myObject = { a: 1, b: 2, c: 3 } console.log(objectMap(myObject, v => 2 * v))


Amberlamps

JS ES10/ES2019의 한 줄짜리는 어떻습니까?

Object.entries()Object.fromEntries() :

 let newObj = Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v * v]));

함수로 작성된 것과 동일한 것:

 function objMap(obj, func) { return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, func(v)])); } // To square each value you can call it like this: let mappedObj = objMap(obj, (x) => x * x);

이 함수는 중첩된 객체를 정사각형으로 만들기 위해 재귀를 사용합니다.

 function objMap(obj, func) { return Object.fromEntries( Object.entries(obj).map(([k, v]) => [k, v === Object(v) ? objMap(v, func) : func(v)] ) ); } // To square each value you can call it like this: let mappedObj = objMap(obj, (x) => x * x);

ES7 / ES2016 에서는 Objects.fromEntries 를 사용할 수 없지만 스프레드 연산자계산된 키 이름 구문과 함께 Object.assign 을 사용하여 동일한 결과를 얻을 수 있습니다.

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

ES6 / ES2015 Object.entries 허용하지 않지만 대신 Object.keys 를 사용할 수 있습니다.

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

ES6은 또한 더 명령적인 스타일을 허용하는 for...of

 let newObj = {} for (let [k, v] of Object.entries(obj)) { newObj[k] = v * v; }


array.reduce()

Object.fromEntries Object.assign 대신에 다음과 같이 reduce 를 사용할 수도 있습니다.

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


상속된 속성과 프로토타입 체인:

드문 경우지만 프로토타입 체인 에 상속된 객체의 속성을 보유 하는 클래스류 객체를 매핑해야 할 수도 있습니다. 이러한 경우 Object.keys()Object.entries() 는 작동하지 않습니다. 이러한 함수에는 프로토타입 체인이 포함되어 있지 않기 때문입니다.

상속된 속성을 매핑해야 하는 경우 for (key in myObj) {...} 사용할 수 있습니다.

다음은 그러한 상황의 예입니다.

 const obj1 = { 'a': 1, 'b': 2, 'c': 3} const obj2 = Object.create(obj1); // One of multiple ways to inherit an object in JS. // Here you see how the properties of obj1 sit on the 'prototype' of obj2 console.log(obj2) // Prints: obj2.__proto__ = { 'a': 1, 'b': 2, 'c': 3} console.log(Object.keys(obj2)); // Prints: an empty Array. console.log(Object.entries(obj2)); // Prints: an empty Array. for (let key in obj2) { console.log(key); // Prints: 'a', 'b', 'c' }

그러나 제발 저에게 은혜를 베풀고 상속을 피하십시오. :-)


Rotareti

기본 메서드는 없지만 lodash#mapValues 는 훌륭하게 작업을 수행합니다.

 _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); // → { 'a': 3, 'b': 6, 'c': 9 }

Mario

하나를 작성하는 것은 매우 쉽습니다.

 Object.map = function(o, f, ctx) { ctx = ctx || this; var result = {}; Object.keys(o).forEach(function(k) { result[k] = f.call(ctx, o[k], k, o); }); return result; }

예제 코드:

 > o = { a: 1, b: 2, c: 3 }; > r = Object.map(o, function(v, k, o) { return v * v; }); > r { a : 1, b: 4, c: 9 }

Array 메서드와 마찬가지로 콜백에 대한 this 컨텍스트를 (선택적으로) 설정할 수도 있습니다.

편집 Object.prototype 사용을 제거하도록 변경되어 개체의 map 이라는 기존 속성과 충돌하지 않도록 합니다.


Alnitak

Object.keys 를 사용한 다음 반환된 키 배열에 대해 forEach 를 사용할 수 있습니다.

 var myObject = { 'a': 1, 'b': 2, 'c': 3 }, newObject = {}; Object.keys(myObject).forEach(function (key) { var value = myObject[key]; newObject[key] = value * value; });

또는 보다 모듈화된 방식으로:

 function map(obj, callback) { var result = {}; Object.keys(obj).forEach(function (key) { result[key] = callback.call(obj, obj[key], key, obj); }); return result; } newObject = map(myObject, function(x) { return x * x; });

Object.keys 는 개체 자체의 열거 가능한 속성만 포함하는 배열을 반환하므로 hasOwnProperty 검사가 for..in 루프처럼 작동합니다.


Mattias Buelens

이것은 정말 짜증나는 일이며 JS 커뮤니티의 모든 사람들이 알고 있습니다. 다음 기능이 있어야 합니다.

 const obj1 = {a:4, b:7}; const obj2 = Object.map(obj1, (k,v) => v + 5); console.log(obj1); // {a:4, b:7} console.log(obj2); // {a:9, b:12}

다음은 순진한 구현입니다.

 Object.map = function(obj, fn, ctx){ const ret = {}; for(let k of Object.keys(obj)){ ret[k] = fn.call(ctx || null, k, obj[k]); }); return ret; };

이것을 항상 직접 구현해야 하는 것은 매우 성가신 일입니다 ;)

Object 클래스를 방해하지 않는 좀 더 정교한 것을 원하면 다음을 시도하십시오.

 let map = function (obj, fn, ctx) { return Object.keys(obj).reduce((a, b) => { a[b] = fn.call(ctx || null, b, obj[b]); return a; }, {}); }; const x = map({a: 2, b: 4}, (k,v) => { return v*2; });

그러나 이 맵 기능을 Object에 추가하는 것이 안전합니다. Object.prototype에는 추가하지 마십시오.

 Object.map = ... // fairly safe Object.prototype.map ... // not ok

Alexander Mills

나는 객체를 배열에 매핑하는 방법을 찾고 답하기 위해 여기에 왔고 결과적으로 이 페이지를 얻었습니다. 나와 같은 답변을 찾기 위해 여기에 온 경우 배열에 매핑하고 개체를 지정하는 방법은 다음과 같습니다.

다음과 같이 맵을 사용하여 객체에서 새 배열을 반환할 수 있습니다.

 var newObject = Object.keys(myObject).map(function(key) { return myObject[key]; });

JoeTron

JavaScript는 새로운 Object.fromEntries 메소드를 얻었습니다.

예시

 function mapObject (obj, fn) { return Object.fromEntries( Object .entries(obj) .map(fn) ) } const myObject = { a: 1, b: 2, c: 3 } const myNewObject = mapObject(myObject, ([key, value]) => ([key, value * value])) console.log(myNewObject)

설명

위의 코드는 객체를 중첩된 배열( [[<key>,<value>], ...] )로 변환하여 매핑할 수 있습니다. Object.fromEntries 는 배열을 다시 개체로 변환합니다.

이 패턴의 멋진 점은 이제 매핑하는 동안 개체 키를 쉽게 고려할 수 있다는 것입니다.

선적 서류 비치

브라우저 지원

Object.fromEntries 는 현재 이러한 브라우저/엔진 에서만 지원되지만 사용 가능한 폴리필(예: @babel/polyfill )이 있습니다.


HaNdTriX

허용되는 답변에는 두 가지 단점이 있습니다.

  • Array.prototype.reduce 오용하는 이유는 이 경우에는 발생하지 않는 복합 유형의 구조를 줄이는 것이 의미하기 때문입니다.
  • 특별히 재사용할 수 없다.

ES6/ES2015 기능적 접근

모든 함수는 커리 형식으로 정의됩니다.

 // small, reusable auxiliary functions const keys = o => Object.keys(o); const assign = (...o) => Object.assign({}, ...o); const map = f => xs => xs.map(x => f(x)); const mul = y => x => x * y; const sqr = x => mul(x) (x); // the actual map function const omap = f => o => { o = assign(o); // A map(x => o[x] = f(o[x])) (keys(o)); // B return o; }; // mock data const o = {"a":1, "b":2, "c":3}; // and run console.log(omap(sqr) (o)); console.log(omap(mul(10)) (o));

  • 라인 A o 는 재할당됩니다. Javascript는 공유 를 통해 참조 값을 전달하기 때문에 o 의 얕은 사본이 생성됩니다. 이제 상위 범위에서 o 를 변경하지 않고 omap 내에서 o
  • B 라인에서 map 의 반환 값은 무시 map o 의 변형을 수행하기 때문입니다. 이 부작용은 omap 내에 남아 있고 상위 범위에서 볼 수 없기 때문에 완전히 허용됩니다.

이것은 가장 빠른 솔루션이 아니라 선언적이고 재사용 가능한 솔루션입니다. 다음은 간결하지만 가독성이 낮은 한 줄짜리 구현과 동일한 구현입니다.

 const omap = f => o => (o = assign(o), map(x => o[x] = f(o[x])) (keys(o)), o);

부록 - 기본적으로 객체를 반복할 수 없는 이유는 무엇입니까?

ES2015는 반복자와 반복 가능한 프로토콜을 지정했습니다. 그러나 객체는 여전히 반복 가능하지 않으므로 매핑할 수 없습니다. 그 이유는 데이터와 프로그램 수준이 혼합되어 있기 때문입니다 .


user6445533

최소 버전(es6):

 Object.entries(obj).reduce((a, [k, v]) => (a[k] = v * v, a), {})

Yukulélé

최대 성능을 위해.

개체가 자주 변경되지 않지만 자주 반복해야 하는 경우 기본 맵을 캐시로 사용하는 것이 좋습니다.

 // example object var obj = {a: 1, b: 2, c: 'something'}; // caching map var objMap = new Map(Object.entries(obj)); // fast iteration on Map object objMap.forEach((item, key) => { // do something with an item console.log(key, item); });

Object.entries는 이미 Chrome, Edge, Firefox 및 베타 Opera에서 작동하므로 미래에도 사용할 수 있는 기능입니다. ES7에서 가져온 것이므로 작동하지 않는 IE의 경우 https://github.com/es-shims/Object.entries를 폴리필하십시오.


Pawel

map 메서드와 forEach 를 사용할 수 있지만 Object 에서 사용하려면 아래와 같이 비틀어서 사용할 수 있습니다.

자바스크립트(ES6) 사용

 var obj = { 'a': 2, 'b': 4, 'c': 6 }; Object.entries(obj).map( v => obj[v[0]] *= v[1] ); console.log(obj); //it will log as {a: 4, b: 16, c: 36} var obj2 = { 'a': 4, 'b': 8, 'c': 10 }; Object.entries(obj2).forEach( v => obj2[v[0]] *= v[1] ); console.log(obj2); //it will log as {a: 16, b: 64, c: 100}

jQuery 사용

 var ob = { 'a': 2, 'b': 4, 'c': 6 }; $.map(ob, function (val, key) { ob[key] *= val; }); console.log(ob) //it will log as {a: 4, b: 16, c: 36}

또는 아래 예제 $.each 메서드와 같은 다른 루프를 사용할 수도 있습니다.

 $.each(ob,function (key, value) { ob[key] *= value; }); console.log(ob) //it will also log as {a: 4, b: 16, c: 36}

Haritsinh Gohil

다음을 사용하여 간단하게 객체를 배열로 변환할 수 있습니다.

객체 값을 배열로 변환할 수 있습니다.

 myObject = { 'a': 1, 'b': 2, 'c': 3 }; let valuesArray = Object.values(myObject); console.log(valuesArray);

객체 키를 배열로 변환할 수 있습니다.

 myObject = { 'a': 1, 'b': 2, 'c': 3 }; let keysArray = Object.keys(myObject); console.log(keysArray);

이제 'map' 기능을 포함한 일반 배열 작업을 수행할 수 있습니다.


Danubio Müller

map function Object.prototype 존재하지 않지만 다음과 같이 에뮬레이트할 수 있습니다.

 var myMap = function ( obj, callback ) { var result = {}; for ( var key in obj ) { if ( Object.prototype.hasOwnProperty.call( obj, key ) ) { if ( typeof callback === 'function' ) { result[ key ] = callback.call( obj, obj[ key ], key, obj ); } } } return result; }; var myObject = { 'a': 1, 'b': 2, 'c': 3 }; var newObject = myMap( myObject, function ( value, key ) { return value * value; });

whitneyit

편집: 최신 JavaScript 기능을 사용하는 표준 방법은 -

 const identity = x => x const omap = (f = identity, o = {}) => Object.fromEntries( Object.entries(o).map(([ k, v ]) => [ k, f(v) ] ) )

여기서 o 는 객체이고 f 는 매핑 함수입니다. 아니면에서 함수 주어진 말할 수있다 a -> b , 그리고 형의 값을 객체 , 형의 값을 객체 생성 a b . 의사 유형 서명으로 -

 // omap : (a -> b, { a }) -> { b }

원래 답변은 변환을 다른 방식으로 생각할 수 있게 해주는 mapReduce 를 보여주기 위해 작성되었습니다.

  1. m , 매핑 기능 – 이전에 들어오는 요소를 변환할 수 있는 기회를 제공합니다.
  2. r , 감소 함수 – 이 함수는 누산기를 매핑된 요소의 결과와 결합합니다.

직관적으로 mapReduce Array.prototype.reduce 직접 연결할 수 있는 새로운 감속기를 만듭니다. 그러나 더 중요한 것은 객체 모노이드, Object.assign{} omap 간단하게 구현할 수 있다는 것입니다.

 const identity = x => x const mapReduce = (m, r) => (a, x) => r (a, m (x)) const omap = (f = identity, o = {}) => Object .keys (o) .reduce ( mapReduce ( k => ({ [k]: f (o[k]) }) , Object.assign ) , {} ) const square = x => x * x const data = { a : 1, b : 2, c : 3 } console .log (omap (square, data)) // { a : 1, b : 4, c : 9 }

실제로 작성해야 하는 프로그램의 유일한 부분은 매핑 구현 자체입니다.

 k => ({ [k]: f (o[k]) })

즉, 알려진 객체 o 와 일부 키 k 주어지면 객체를 구성하고 계산된 속성 k 가 키 값 o[k] f 를 호출한 결과입니다.

우리는 엿볼 수 mapReduce 의 순서 잠재력을 경우 우리는 첫째 추상적 인 oreduce

 // oreduce : (string * a -> string * b, b, { a }) -> { b } const oreduce = (f = identity, r = null, o = {}) => Object .keys (o) .reduce ( mapReduce ( k => [ k, o[k] ] , f ) , r ) // omap : (a -> b, {a}) -> {b} const omap = (f = identity, o = {}) => oreduce ( mapReduce ( ([ k, v ]) => ({ [k]: f (v) }) , Object.assign ) , {} , o )

모든 것이 동일하게 작동하지만 omap 을 더 높은 수준에서 정의할 수 있습니다. 물론 새로운 Object.entries 는 이것을 어리석게 보이게 하지만, 이 연습은 여전히 학습자에게 중요합니다.

mapReduce 의 모든 잠재력을 볼 수 없지만 적용할 수 있는 위치를 확인하는 것이 흥미로워서 이 답변을 공유합니다. 파생된 방법 및 유용할 수 있는 다른 방법에 관심이 있는 경우 이 답변을 참조하십시오.


Mulan

나는 이것을 배우려고 시도하는 Google 검색의 첫 번째 항목으로 이것을 발견했으며, npm 패키지를 불변으로 사용하는 내가 찾은 솔루션을 최근에 찾은 다른 사람들을 위해 공유할 것이라고 생각했습니다.

immutable이 자체 문서에서 OP의 EXACT 상황을 사용하기 때문에 공유하는 것이 흥미롭다고 생각합니다. 다음은 내 코드가 아니라 현재 immutable-js 문서에서 가져온 것입니다.

 const { Seq } = require('immutable') const myObject = { a: 1, b: 2, c: 3 } Seq(myObject).map(x => x * x).toObject(); // { a: 1, b: 4, c: 9 }

Seq에는 다른 속성("Seq는 지연 작업을 설명하므로 중간 컬렉션을 생성하지 않음으로써 모든 고차 컬렉션 메서드(예: 맵 및 필터)의 사용을 효율적으로 연결할 수 있습니다") 및 일부 다른 immutable-js 데이터가 있다는 것은 아닙니다. 구조는 작업을 매우 효율적으로 수행할 수도 있습니다.

이 방법을 사용하는 사람은 물론 npm install immutable 하며 문서를 읽고 싶을 수 있습니다.

https://facebook.github.io/immutable-js/


alex.h

@Amberlamps 답변을 기반으로 다음은 유틸리티 기능입니다(댓글로 보기에 보기 흉했습니다).

 function mapObject(obj, mapFunc){ return Object.keys(obj).reduce(function(newObj, value) { newObj[value] = mapFunc(obj[value]); return newObj; }, {}); }

용도는 다음과 같습니다.

 var obj = {a:1, b:3, c:5} function double(x){return x * 2} var newObj = mapObject(obj, double); //=> {a: 2, b: 6, c: 10}

yonatanmn

내 응답은 대부분 여기에서 가장 높은 평가를 받은 응답을 기반으로 하며 모든 사람이 이해하기를 바랍니다(내 GitHub에도 동일한 설명이 있습니다). 이것이 그의 지도 구현이 작동하는 이유입니다.

 Object.keys(images).map((key) => images[key] = 'url(' + '"' + images[key] + '"' + ')');

이 함수의 목적은 배열을 반환하지 않고 모든 객체(객체와 배열 모두)에서 사용할 수 있는 메서드를 사용하여 객체를 가져와 객체의 원래 내용을 수정하는 것입니다. JS 내의 거의 모든 것이 객체이며, 그 때문에 상속 파이프라인의 더 아래에 있는 요소는 잠재적으로 기술적으로 상위 라인에 있는 요소를 사용할 수 있습니다.

이것이 작동하는 이유는 단순히 기존 객체를 수정하는 대신 배열의 명시적 또는 암시적 RETURN을 제공해야 하는 배열을 반환하는 .map 함수 때문입니다. 개별 키가 연결된 값에 대해 작동하는 맵 기능을 사용할 수 있도록 하는 Object.keys를 사용하여 개체가 배열이라고 프로그램을 속이는 것이 기본적으로 됩니다(실제로 실수로 배열을 반환했지만 수정했습니다). 정상적인 의미에서 반환이 없는 한 원래 개체가 그대로 유지되고 프로그래밍된 대로 수정된 배열이 생성되지 않습니다.

이 특정 프로그램은 이미지라는 객체를 가져와서 키 값을 취하고 다른 함수 내에서 사용하기 위해 url 태그를 추가합니다. 원본은 이렇습니다.

 var images = { snow: 'https://www.trbimg.com/img-5aa059f5/turbine/bs-md-weather-20180305', sunny: 'http://www.cubaweather.org/images/weather-photos/large/Sunny-morning-east- Matanzas-city- Cuba-20170131-1080.jpg', rain: 'https://i.pinimg.com/originals/23/d8 /ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg' };

...수정된 내용은 다음과 같습니다.

 var images = { snow: url('https://www.trbimg.com/img-5aa059f5/turbine/bs-md-weather-20180305'), sunny: url('http://www.cubaweather.org/images/weather-photos/large/Sunny-morning- east-Matanzas-city- Cuba-20170131-1080.jpg'), rain: url('https://i.pinimg.com/originals/23/d8 /ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg') };

객체의 원래 구조는 반환이 없는 한 정상적인 속성 액세스를 허용하는 그대로 남아 있습니다. 정상처럼 배열을 반환하지 마십시오. 그러면 모든 것이 잘 될 것입니다. 목표는 원래 값(images[key])을 다른 것이 아닌 원하는 것으로 재지정하는 것입니다. 내가 아는 한, 배열 출력을 방지하려면 이미지[키]의 REASSIGNMENT가 있어야 하고 배열을 반환하라는 암시적 또는 명시적 요청이 없어야 합니다(변수 할당이 이 작업을 수행하고 나를 위해 앞뒤로 결함이 발생했습니다).

편집하다:

원래 객체 수정을 피하기 위해 새 객체 생성과 관련된 다른 방법을 다루려고 합니다(그리고 실수로 배열을 출력으로 생성하는 것을 방지하기 위해 재할당이 여전히 필요한 것으로 보입니다). 이러한 함수는 화살표 구문을 사용하며 나중에 사용하기 위해 단순히 새 객체를 생성하려는 경우에 사용됩니다.

 const mapper = (obj, mapFn) => Object.keys(obj).reduce((result, key) => { result[key] = mapFn(obj)[key]; return result; }, {}); var newImages = mapper(images, (value) => value);

이러한 기능이 작동하는 방식은 다음과 같습니다.

mapFn은 나중에 추가될 함수(이 경우 (값) => 값)를 취하고 mapFn( obj)[키],

그런 다음 result[key] = mapFn(obj)[key]의 키와 관련된 원래 값을 재정의합니다.

결과에 대해 수행된 연산을 반환합니다(.reduce 함수의 끝에서 시작된 대괄호에 있는 누산기).

이 모든 것은 선택된 객체에서 수행되고 있으며 여전히 반환된 배열에 대한 암시적 요청이 있을 수 없으며 내가 말할 수 있는 한 값을 재할당할 때만 작동합니다. 이를 위해서는 약간의 정신 체조가 필요하지만 위에서 볼 수 있는 것처럼 필요한 코드 라인이 줄어듭니다. 출력은 아래에서 볼 수 있는 것과 정확히 동일합니다.

 {snow: "https://www.trbimg.com/img-5aa059f5/turbine/bs- md-weather-20180305", sunny: "http://www.cubaweather.org/images/weather- photos/l…morning-east-Matanzas-city-Cuba-20170131-1080.jpg", rain: "https://i.pinimg.com/originals/23/d8 /ab/23d8ab1eebc72a123cebc80ce32b43d8.jpg"}

이것은 NON-NUMBERS에서 작동했음을 명심하십시오. mapFN 함수에서 값을 단순하게 반환하여 모든 개체를 복제할 수 있습니다.


Andrew Ramshaw

값뿐만 아니라 키도 map 하는 데 관심이 있다면 다음과 같이 동작하는 Object.map(valueMapper, keyMapper)

 var source = { a: 1, b: 2 }; function sum(x) { return x + x } source.map(sum); // returns { a: 2, b: 4 } source.map(undefined, sum); // returns { aa: 1, bb: 2 } source.map(sum, sum); // returns { aa: 2, bb: 4 }

MattiSG

키를 수정할 수 있는 버전도 필요했습니다(@Amberlamps 및 @yonatanmn 답변 기반).

 var facts = [ // can be an object or array - see jsfiddle below {uuid:"asdfasdf",color:"red"}, {uuid:"sdfgsdfg",color:"green"}, {uuid:"dfghdfgh",color:"blue"} ]; var factObject = mapObject({}, facts, function(key, item) { return [item.uuid, {test:item.color, oldKey:key}]; }); function mapObject(empty, obj, mapFunc){ return Object.keys(obj).reduce(function(newObj, key) { var kvPair = mapFunc(key, obj[key]); newObj[kvPair[0]] = kvPair[1]; return newObj; }, empty); }

사실 개체=

 { "asdfasdf": {"color":"red","oldKey":"0"}, "sdfgsdfg": {"color":"green","oldKey":"1"}, "dfghdfgh": {"color":"blue","oldKey":"2"} }

편집: 시작 객체 {}에서 전달하기 위한 약간의 변경. [] 허용(키가 정수인 경우)


Symmetric

var myObject = { 'a': 1, 'b': 2, 'c': 3 }; Object.prototype.map = function(fn){ var oReturn = {}; for (sCurObjectPropertyName in this) { oReturn[sCurObjectPropertyName] = fn(this[sCurObjectPropertyName], sCurObjectPropertyName); } return oReturn; } Object.defineProperty(Object.prototype,'map',{enumerable:false}); newObject = myObject.map(function (value, label) { return value * value; }); // newObject is now { 'a': 1, 'b': 4, 'c': 9 }

Dmitry Ragozin

더 밀접하게 정확하게 OP가 무엇을 요구에 응답까지, 영업 이익은 개체를 원하는 :

myObject = { 'a': 1, 'b': 2, 'c': 3 }

myObject.map 을 가지려면

다음과 같이 사용되는 Array.prototype.map과 유사합니다.

 newObject = myObject.map(함수(값, 레이블) {
    반환 값 * 값;
});
// newObject는 이제 { 'a': 1, 'b': 4, 'c': 9 }

imho best(" 요청한 것에 가깝다 " + "불필요하게 ES{5,6,7}이 필요하지 않음"으로 측정됨) 답변은 다음과 같습니다.

 myObject.map = function mapForObject(callback) { var result = {}; for(var property in this){ if(this.hasOwnProperty(property) && property != "map"){ result[property] = callback(this[property],property,this); } } return result; }

위의 코드는 최신 ECMAScript 버전에서만 사용할 수 있는 언어 기능을 의도적으로 사용하는 것을 방지합니다. 위의 코드를 사용하면 다음과 같이 문제를 해결할 수 있습니다.

 myObject = { 'a': 1, 'b': 2, 'c': 3 }; myObject.map = function mapForObject(callback) { var result = {}; for(var property in this){ if(this.hasOwnProperty(property) && property != "map"){ result[property] = callback(this[property],property,this); } } return result; } newObject = myObject.map(function (value, label) { return value * value; }); console.log("newObject is now",newObject);
여기에 대체 테스트 코드

일부에서는 눈살을 찌푸리게 하는 것 외에도 프로토타입 체인에 이와 같이 솔루션을 삽입할 가능성이 있습니다.

 Object.prototype.map = function(callback) { var result = {}; for(var property in this){ if(this.hasOwnProperty(property)){ result[property] = callback(this[property],property,this); } } return result; }

주의 감독으로 수행 뭔가, 어떤 부작용이 아닌 영향이 없어야 map 다른 개체의 방법 (즉, 배열의 map ).


humanityANDpeace

먼저 Object.entries(collection)를 사용하여 HTMLCollection을 변환합니다. 그런 다음 반복 가능하므로 이제 .map 메서드를 사용할 수 있습니다.

 Object.entries(collection).map(...)

참조 https://medium.com/@js_tut/calling-javascript-code-on-multiple-div-elements-without-the-id-attribute-97ff6a50f31


Jimubao

TypeScript의 개체 매퍼

내가 사용하는 예와 같은 Object.fromEntries이 하나 ,하지만 여전히 그들은 매우 쉽게 사용할 수 없습니다. Object.keys 를 사용한 key 를 조회하는 답변은 실제로 필요하지 않을 수 있는 여러 조회를 수행하고 있습니다.

나는이 였으면 Object.map 기능을하지만, 우리는 자신의 우리를 만들고 호출 할 수 있습니다 objectMap 모두 수정할 수있는 기능 keyvalue :

사용법(자바스크립트):

 const myObject = { 'a': 1, 'b': 2, 'c': 3 }; // keep the key and modify the value let obj = objectMap(myObject, val => val * 2); // obj = { a: 2, b: 4, c: 6 } // modify both key and value obj = objectMap(myObject, val => val * 2 + '', key => (key + key).toUpperCase()); // obj = { AA: '2', BB: '4', CC: '6' }

코드(TypeScript):

 interface Dictionary<T> { [key: string]: T; } function objectMap<TValue, TResult>( obj: Dictionary<TValue>, valSelector: (val: TValue, obj: Dictionary<TValue>) => TResult, keySelector?: (key: string, obj: Dictionary<TValue>) => string, ctx?: Dictionary<TValue> ) { const ret = {} as Dictionary<TResult>; for (const key of Object.keys(obj)) { const retKey = keySelector ? keySelector.call(ctx || null, key, obj) : key; const retVal = valSelector.call(ctx || null, obj[key], obj); ret[retKey] = retVal; } return ret; }

TypeScript를 사용하지 않는 경우 TypeScript Playground 에서 위의 코드를 복사하여 JavaScript 코드를 가져옵니다.

또한, 내가 넣어 이유 keySelector 한 후 valSelector 는 선택 사항이기 때문에 매개 변수 목록이다.

* 일부 크레딧은 alexander-mills의 답변으로 이동합니다.


orad

const mapObject = (targetObject, callbackFn) => { if (!targetObject) return targetObject; if (Array.isArray(targetObject)){ return targetObject.map((v)=>mapObject(v, callbackFn)) } return Object.entries(targetObject).reduce((acc,[key, value]) => { const res = callbackFn(key, value); if (!Array.isArray(res) && typeof res ==='object'){ return {...acc, [key]: mapObject(res, callbackFn)} } if (Array.isArray(res)){ return {...acc, [key]: res.map((v)=>mapObject(v, callbackFn))} } return {...acc, [key]: res}; },{}) }; const mapped = mapObject(a,(key,value)=> { if (!Array.isArray(value) && key === 'a') return ; if (!Array.isArray(value) && key === 'e') return []; if (!Array.isArray(value) && key === 'g') return value * value; return value; }); console.log(JSON.stringify(mapped)); // {"b":2,"c":[{"d":2,"e":[],"f":[{"g":4}]}]}

이 함수는 객체와 객체 배열을 재귀적으로 진행합니다. 정의되지 않은 상태로 반환되면 속성을 삭제할 수 있습니다.


Stan

값뿐만 아니라 키도 선택적으로 매핑하는 기능이 필요했습니다. 원래 개체는 변경되지 않아야 합니다. 개체에는 기본 값만 포함되어 있습니다.

 function mappedObject(obj, keyMapper, valueMapper) { const mapped = {}; const keys = Object.keys(obj); const mapKey = typeof keyMapper == 'function'; const mapVal = typeof valueMapper == 'function'; for (let i = 0; i < keys.length; i++) { const key = mapKey ? keyMapper(keys[i]) : keys[i]; const val = mapVal ? valueMapper(obj[keys[i]]) : obj[keys[i]]; mapped[key] = val; } return mapped; }

사용하다. keymapper와 valuemapper 함수를 전달합니다.

 const o1 = { x: 1, c: 2 } mappedObject(o1, k => k + '0', v => v + 1) // {x0: 2, c0: 3}

Emilio Grisolía

Hey는 도움이 될 수 있는 작은 매퍼 기능을 작성했습니다.

 function propertyMapper(object, src){ for (var property in object) { for (var sourceProp in src) { if(property === sourceProp){ if(Object.prototype.toString.call( property ) === '[object Array]'){ propertyMapper(object[property], src[sourceProp]); }else{ object[property] = src[sourceProp]; } } } } }

Zak

누군가 객체를 새 객체나 배열에 매핑하는 간단한 솔루션을 찾고 있다면:

 // Maps an object to a new object by applying a function to each key+value pair. // Takes the object to map and a function from (key, value) to mapped value. const mapObject = (obj, fn) => { const newObj = {}; Object.keys(obj).forEach(k => { newObj[k] = fn(k, obj[k]); }); return newObj; }; // Maps an object to a new array by applying a function to each key+value pair. // Takes the object to map and a function from (key, value) to mapped value. const mapObjectToArray = (obj, fn) => ( Object.keys(obj).map(k => fn(k, obj[k])) );

이것은 모든 개체 또는 모든 매핑 기능에 대해 작동하지 않을 수 있지만 내가 필요로 하는 단순한 얕은 개체와 간단한 매핑 기능에는 작동합니다.


tailattention

다른 방법은 깊은 객체에서도 작동할 수 있는 사용자 지정 json stringify 함수를 사용하는 것입니다. 어쨌든 json으로 서버에 게시하려는 경우 유용할 수 있습니다.

 const obj = { 'a': 1, 'b': 2, x: {'c': 3 }} const json = JSON.stringify(obj, (k, v) => typeof v === 'number' ? v * v : v) console.log(json) console.log('back to json:', JSON.parse(json))


Endless

면제를 줄이기 위해 문자열만 처리합니다.

 Object.keys(params).map(k => typeof params[k] == "string" ? params[k] = params[k].trim() : null);

Idan

출처 : http:www.stackoverflow.com/questions/14810506/map-function-for-objects-instead-of-arrays

반응형