Giter VIP home page Giter VIP logo

map-obj's Introduction

map-obj

Map object keys and values into a new object

Install

npm install map-obj

Usage

import mapObject, {mapObjectSkip} from 'map-obj';

const newObject = mapObject({foo: 'bar'}, (key, value) => [value, key]);
//=> {bar: 'foo'}

const newObject = mapObject({FOO: true, bAr: {bAz: true}}, (key, value) => [key.toLowerCase(), value]);
//=> {foo: true, bar: {bAz: true}}

const newObject = mapObject({FOO: true, bAr: {bAz: true}}, (key, value) => [key.toLowerCase(), value], {deep: true});
//=> {foo: true, bar: {baz: true}}

const newObject = mapObject({one: 1, two: 2}, (key, value) => value === 1 ? [key, value] : mapObjectSkip);
//=> {one: 1}

API

mapObject(source, mapper, options?)

source

Type: object

The source object to copy properties from.

mapper

Type: (sourceKey, sourceValue, source) => [targetKey, targetValue, mapperOptions?] | mapObjectSkip

A mapping function.

mapperOptions

Type: object

shouldRecurse

Type: boolean
Default: true

Whether targetValue should be recursed.

Requires deep: true.

options

Type: object

deep

Type: boolean
Default: false

Recurse nested objects and objects in arrays.

target

Type: object
Default: {}

The target object to map properties on to.

mapObjectSkip

Return this value from a mapper function to exclude the key from the new object.

import mapObject, {mapObjectSkip} from 'map-obj';

const object = {one: 1, two: 2}
const mapper = (key, value) => value === 1 ? [key, value] : mapObjectSkip
const result = mapObject(object, mapper);

console.log(result);
//=> {one: 1}

Related

  • filter-obj - Filter object keys and values into a new object

Get professional support for this package with a Tidelift subscription
Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.

map-obj's People

Contributors

bendingbender avatar bendrucker avatar coreyfarrell avatar faizanu94 avatar gr2m avatar jamestalmage avatar ninevra avatar richienb avatar rocktimsaikia avatar samverschueren avatar sindresorhus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

map-obj's Issues

Pass arguments to mapArray

Hey,

I just looked through your code to see if your package does what I need.
This library could consume less memory (I think) by moving mapArray out of mapObj and pass the arguments along - just like you pass them into mapObj.
Currently a new function is created for each recursive call. For big objects that might be quite some memory, I guess.

Add ability to remove a key

Would you accept a pull request which implements the following?

mapObject({one: 1, two: 2}, (key, value) => value === 1 ? [key, value] : null);
//=> {one: 1}

The code change will look like this

-let [newKey, newValue, {shouldRecurse = true} = {}] = mapper(key, value, object);
+let mapResult = mapper(key, value, object)
+if (mapResult === null) continue
+let [newKey, newValue, {shouldRecurse = true} = {}] = mapResult

Publish new release

Hi, is it possible for you to publish a new release ?
I would like to have the new shouldRecurse feature.
Thanks.

TypeError: Invalid value used as weak map key

Sorry, I opened an issue in your oher repo, not sure where I should open this issue

TypeError: Invalid value used as weak map key
    at WeakMap.set (native)
    at mapObj (/home/jperelli/celerative/wysh/WYSHAPI/node_modules/map-obj/index.js:23:7)
    at module.exports (/home/jperelli/celerative/wysh/WYSHAPI/node_modules/camelcase-keys/index.js:16:9)

What could be causing this error?

Problem with recurse nested objects

I found that if you have a Blob instance or File instance within object which passed in mapObject and deep is true the function will go inside this objects. I guess it is not correct because Blob and File are js's special objects and this logic breaks them. If you add a simple check like !(value instanceof Blob) here that will fix this problem. I can create PR.

Access to parent key

Hey,

I have a use case where I don't map keys but values.
It would be useful for me to be able to access the parent's key (which is unchanged in my case) or even a list of all parents, grand-parents etc.

I realize that when mapping keys this may not make much sense but I also think there could be use cases.

Provide dot-prop-like keys

Useful for pinpointing exactly where a key is in an object. Useful to determine where a key is located in a deep object:

const mapObject = require("map-obj")

mapObject({
	a: {
		b: "๐Ÿฆ„"
	}
}, (key, value) => {
	console.log(key)

	return [key, value]
}, {
	deep: true,
	dotPropKeys: true
})
//=> "a"
//=> "a.b"

`__proto__` keys assign to the prototype

If a mapper function produces ['__proto__', value], rather than create a corresponding own property, mapObject sets the prototype of the target object to the output value.

This prevents objects containing __proto__ keys from round-tripping through the identity function, and prevents mappers from producing __proto__ keys.

One possible fix is to use Object.defineProperty() for creating properties, rather than assignment. However, this would also change mapObject's behavior in certain edge cases when given custom target objects: their setters would not invoked, their non-writable own properties would be overwritten with writable properties, and writable non-configurable own properties would throw TypeErrors. Would that be considered a breaking change?

I'll submit a PR adding failing test cases.

Throw error on Arrays.

The library is not supposed to accept arrays. And it does not throw any errors on passing one too.

const newObj = mapObject([2, 1], (key, value) => [value, key]);

console.log(newObj)
//=> outputs
[ 2, 1 ]

This is due to this check. Since arrays are objects too, It lets them slide in.

const isObject = value => typeof value === 'object' && value !== null;



We can use the is-plain-obj package here to check only plain objects and update the docs to clearly specify that this lib is only for plain objects.

Add async support?

import mapObject from 'map-obj-async';

const newObject = await mapObject({
   url: 'https://www.google.com/'
}, async (key, value) => [key, await fetchHtml(value)]);
//=> { url: `<!DOCTYPE html>...` }

I forked and published https://github.com/richardscarrott/map-obj-async but thought it was worth opening an issue here just in case you wanted to support it? (Although not 100% sure there's a particularly nice way to support both sync and async in a single impl.)

TypeScript 3.5 incompatible

node_modules/map-obj/index.d.ts:72:3 - error TS2344: Type 'SourceObjectType' does not satisfy the constraint '{ [key: string]: unknown; }'.
Type 'object' is not assignable to type '{ [key: string]: unknown; }'.

72 SourceObjectType,
~~~~~~~~~~~~~~~~

node_modules/p-queue/index.d.ts:79:47 - error TS2344: Type 'DefaultAddOptions' does not satisfy the constraint 'QueueAddOptions'.
Index signature is missing in type 'DefaultAddOptions'.

79 EnqueueOptionsType extends QueueAddOptions = DefaultAddOptions

allow falsy return value as a sort of "filter"

If they return a falsie value, skip this key/value pair.

It might be safest if you make them explicitly return a specific value(false or null), to guard against accidental returns of undefined.

[BUG] Incorrect `source` argument passed to the `mapper` function

Right now, the source argument passed to the mapper function is not the actual original source argument the user passed to mapObject, but the "owner" object of the key/value pair for the current iteration.

Example:

const { default: mapObject } = await import('./index.js');
const subject = { nestedA: { one: 1, two: 2 }, nestedB: { three: 3, four: 4 } };
const mapper = (key, value, source) => source !== subject ? [key + '_different', value] : [key + '_same', value];
console.log(mapObject(subject, mapper, { deep: true }));
{
  nestedA_same: { one_different: 1, two_different: 2 },
  nestedB_same: { three_different: 3, four_different: 4 }
}

Notice source is only equal to subject for the top level keys.

Fixing this would be a breaking change, so should probably be released as v6.0.0?

browserify

I know you don't want to publish babelified versions of your module, and you prefer your users takes care of that.

But in order to do that, I have to manually change map-obj package.json every time I deploy, to add:

"browserify": {
    "transform": [
      "babelify"
    ]
  }

would you accept a PR to add that code to pkg file?

Types when passing { deep: true } are wrong

The types type the key and value arguments as keys and values of the passed root object, but when passing { deep: true }, my understanding is these could be deeply nested keys and values (i.e. key: string and value: unknown)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.