[javascript] 객체 대신지도 함수 (배열 대신)

나는 물건을 가지고있다 :

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에서 이것을 원하므로 크로스 브라우저 문제는 신경 쓰지 않습니다.)



답변

이 네이티브 없다 map받는 Object객체,하지만 어떻게 이것에 대해 :

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키 값이 두 배로 새 키 가 추가됩니다.

최신 정보

새로운 ES6 기능으로보다 우아한 표현 방법이 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)) 


답변

일반 JS ( ES6 / ES2015 ) 에서 즉시 변수를 할당하는 하나의 라이너는 어떻습니까?

사용 만들기 확산 연산자계산 된 키 이름 구문 :

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

jsbin

reduce를 사용하는 다른 버전 :

let newObj = Object.keys(obj).reduce((p, c) => ({...p, [c]: obj[c] * obj[c]}), {});

jsbin

함수로서의 첫 번째 예 :

const oMap = (o, f) => Object.assign({}, ...Object.keys(o).map(k => ({ [k]: f(o[k]) })));

// To square each value you can call it like this:
let mappedObj = oMap(myObj, (x) => x * x);

jsbin

중첩 된 객체를 매핑 할 경우 재귀 A의 기능적인 스타일, 그것은 다음과 같이 수행 할 수 있습니다 :

const sqrObjRecursive = obj =>
  Object.keys(obj).reduce(
    (newObj, key) =>
      obj[key] && typeof obj[key] === "object"
        ? { ...newObj, [key]: sqrObjRecursive(obj[key]) } // recurse.
        : { ...newObj, [key]: obj[key] * obj[key] }, // square val.
    {}
  );       

jsbin

또는 더 필수적으로 다음과 같이하십시오.

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

jsbin

ES7 / ES2016 부터 다음과 같이 Object.entries()대신 사용할 수 있습니다 Object.keys().

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

ES2019가 도입 Object.fromEntries()되어 더욱 단순화 되었습니다 .

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

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

드문 경우지만 프로토 타입 체인 에서 상속 된 객체의 속성을 보유 하는 클래스와 유사한 객체 를 매핑해야 할 수도 있습니다 . 상속 된 속성을 열거하지 않기 때문에 이러한 경우 에는 작동 하지 않습니다 . 상속 된 속성 을 매핑해야하는 경우을 사용해야합니다 .Object.keys()Object.keys()for (key in myObj) {...}

다음은 다른 객체의 속성을 상속하는 객체의 예 Object.keys()와 이러한 시나리오에서 작동하지 않는 방법 입니다.

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.

for (key in obj2) {
  console.log(key);              // Prints: 'a', 'b', 'c'
}

jsbin

그러나 부탁을 들어 주시고 상속을 피하십시오 . 🙂


답변

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

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


답변

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

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 }

NB :이 버전 this에서는 Array메소드 와 마찬가지로 콜백 의 컨텍스트를 설정 (선택 사항) 할 수도 있습니다 .

EDIT- 객체의 Object.prototype이름이 기존 속성과 충돌하지 않도록의 사용을 제거하도록 변경되었습니다 map.


답변

반환 된 키 배열을 사용한 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객체 자체의 열거 가능한 속성 만 포함하는 배열 을 반환하므로 검사가 있는 for..in루프 처럼 동작 hasOwnProperty합니다.


답변

이것은 바로 bs이며 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


답변

객체를 배열에 매핑하기 위해 찾고 답하기 위해 여기에 왔으며 결과적 으로이 페이지를 얻었습니다. 내가 가진 것과 똑같은 답을 찾고 여기 온다면 배열에 매핑하고 객체를 지정하는 방법입니다.

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

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