Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 1095 Vote(s) - 3.45 Average
  • 1
  • 2
  • 3
  • 4
  • 5
map function for objects (instead of arrays)

#11
The accepted answer has two drawbacks:

- It misuses `Array.prototype.reduce`, because reducing means to change the structure of a composite type, which doesn't happen in this case.
- It is not particularly reusable

---

### An ES6/ES2015 functional approach

Please note that all functions are defined in curried form.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// 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));
<!-- end snippet -->

- In line A `o` is reassigned. Since Javascript passes reference values [by sharing](

[To see links please register here]

), a shallow copy of `o` is generated. We are now able to mutate `o` within `omap` without mutating `o` in the parent scope.
- In line B `map`'s return value is ignored, because `map` performs a mutation of `o`. Since this side effect remains within `omap` and isn't visible in the parent scope, it is totally acceptable.

This is not the fastest solution, but a declarative and reusable one. Here is the same implementation as a one-line, succinct but less readable:

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

---

### Addendum - why are objects not iterable by default?

ES2015 specified the iterator and iterable protocols. But objects are still not iterable and thus not mappable. [The reason is the mixing of data and program level](

[To see links please register here]

).
Reply

#12
I specifically wanted to use the same function that I was using for arrays for a single object, and wanted to keep it simple. This worked for me:

var mapped = [item].map(myMapFunction).pop();
Reply

#13
For maximum performance.

If your object doesn't change often but needs to be iterated on often I suggest using a native Map as a cache.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

// 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);
});

<!-- end snippet -->

Object.entries already works in Chrome, Edge, Firefox and beta Opera so it's a future-proof feature.
It's from ES7 so polyfill it

[To see links please register here]

for IE where it doesn't work.
Reply

#14
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 }
Reply

#15
I came upon this as a first-item in a Google search trying to learn to do this, and thought I would share for other folsk finding this recently the solution I found, which uses the npm package immutable.

I think its interesting to share because immutable uses the OP's EXACT situation in their own documentation - the following is not my own code but pulled from the current immutable-js documentation:

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 }

Not that Seq has other properties ("Seq describes a lazy operation, allowing them to efficiently chain use of all the higher-order collection methods (such as map and filter) by not creating intermediate collections") and that some other immutable-js data structures might also do the job quite efficiently.

Anyone using this method will of course have to `npm install immutable` and might want to read the docs:

[To see links please register here]

Reply

#16


<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

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

const result = _.transform(orig, (r, v, k) => r[k.trim()] = v * 2);

console.log(result);

<!-- language: lang-html -->

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


<!-- end snippet -->

Use new [ _.transform() to transforms object][1].


[1]:

[To see links please register here]

Reply

#17
If anyone was looking for a simple solution that maps an object to a new object or to an array:

// 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]))
);

This may not work for all objects or all mapping functions, but it works for plain shallow objects and straightforward mapping functions which is all I needed.
Reply

#18
A different take on it is to use a custom json stringify function that can also work on deep objects. This might be useful if you intend to post it to the server anyway as json

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

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

<!-- end snippet -->

Reply

#19
you can use `map` method and `forEach` on arrays but if you want to use it on `Object` then you can use it with twist like below:

**Using Javascript (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}

**Using 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}
Or you can use other loops also like `$.each` method as below example:

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

#20
To responds more closely to what *precisely* the OP asked for, the OP wants an object:

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

to have a map method `myObject.map`,

> similar to Array.prototype.map that would be used as follows:

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

The *imho* best (measured in terms to "*close to what is asked*" + "no ES{5,6,7} required needlessly") answer would be:


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;
}

The code above avoids intentionally using any language features, only available in recent ECMAScript editions. With the code above the problem can be solved lke this:

<!-- begin snippet: js hide: false -->

<!-- language: lang-js -->

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);

<!-- end snippet -->
[alternative test code here][1]

Besides frowned upon by some, it would be a possibility to insert the solution in the prototype chain like this.


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;
}

Something, which when done with careful oversight should not have any ill effects and not impact `map` method of other objects (i.e. Array's `map`).


[1]:

[To see links please register here]

=
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through