Skip to content

Commit 30466a3

Browse files
committed
use split-string, simplify
1 parent 84adad4 commit 30466a3

File tree

3 files changed

+69
-40
lines changed

3 files changed

+69
-40
lines changed

index.js

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,57 +7,45 @@
77

88
'use strict';
99

10-
var toPath = require('to-object-path');
10+
var split = require('split-string');
1111
var extend = require('extend-shallow');
1212
var isPlainObject = require('is-plain-object');
1313
var isObject = require('is-extendable');
1414

15-
module.exports = function(obj, path, val) {
15+
module.exports = function(obj, prop, val) {
1616
if (!isObject(obj)) {
1717
return obj;
1818
}
1919

20-
if (Array.isArray(path)) {
21-
path = toPath(path);
20+
if (Array.isArray(prop)) {
21+
prop = [].concat.apply([], prop).join('.');
2222
}
2323

24-
if (typeof path !== 'string') {
24+
if (typeof prop !== 'string') {
2525
return obj;
2626
}
2727

28-
var segs = path.split('.');
29-
var len = segs.length, i = -1;
30-
var res = obj;
31-
var last;
32-
33-
while (++i < len) {
34-
var key = segs[i];
35-
36-
while (key[key.length - 1] === '\\') {
37-
key = key.slice(0, -1) + '.' + segs[++i];
38-
}
39-
40-
if (i === len - 1) {
41-
last = key;
42-
break;
43-
}
44-
45-
if (!isObject(obj[key])) {
46-
obj[key] = {};
28+
var keys = split(prop, {sep: '.', brackets: true});
29+
var len = keys.length;
30+
var idx = -1;
31+
var current = obj;
32+
33+
while (++idx < len) {
34+
var key = keys[idx];
35+
if (idx !== len - 1) {
36+
if (!isObject(current[key])) {
37+
current[key] = {};
38+
}
39+
current = current[key];
40+
continue;
4741
}
48-
obj = obj[key];
49-
}
5042

51-
if (obj.hasOwnProperty(last) && isObject(obj[last])) {
52-
if (isPlainObject(val)) {
53-
extend(obj[last], val);
43+
if (isPlainObject(current[key]) && isPlainObject(val)) {
44+
current[key] = extend({}, current[key], val);
5445
} else {
55-
obj[last] = val;
46+
current[key] = val;
5647
}
57-
58-
} else {
59-
obj[last] = val;
6048
}
61-
return res;
62-
};
6349

50+
return obj;
51+
};

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
"dependencies": {
2828
"extend-shallow": "^2.0.1",
2929
"is-extendable": "^0.1.1",
30-
"is-plain-object": "^2.0.1",
31-
"to-object-path": "^0.3.0"
30+
"is-plain-object": "^2.0.3",
31+
"split-string": "^3.0.1"
3232
},
3333
"devDependencies": {
3434
"gulp-format-md": "^0.1.12",
35-
"mocha": "^3.4.1"
35+
"mocha": "^3.4.2"
3636
},
3737
"keywords": [
3838
"get",

test.js

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ describe('set', function() {
111111
assert.deepEqual(actual, {a: 'a', b: {c: {d: 'eee'}}});
112112
});
113113

114+
it('should work with nested arrays in keys', function() {
115+
var actual = set({a: 'a', b: {c: 'd'}}, [['b'], ['c', 'd']], 'eee');
116+
assert.deepEqual(actual, {a: 'a', b: {c: {d: 'eee'}}});
117+
});
118+
114119
it('should set a deeply nested value.', function() {
115120
var actual = set({a: 'a', b: {c: 'd'}}, 'b.c.d', 'eee');
116121
assert.deepEqual(actual, {a: 'a', b: {c: {d: 'eee'}}});
@@ -141,13 +146,49 @@ describe('set', function() {
141146
});
142147

143148
describe('escaping', function() {
144-
it('should recognize escaped dots:', function() {
149+
it('should not split inside double quotes:', function() {
150+
var o = {};
151+
set(o, 'a."b.c.d".e', 'c');
152+
assert.equal(o.a['b.c.d'].e, 'c');
153+
});
154+
155+
it('should not split inside single quotes:', function() {
156+
var o = {};
157+
set(o, "a.'b.c.d'.e", 'c');
158+
assert.equal(o.a['b.c.d'].e, 'c');
159+
});
160+
161+
it('should not split inside square brackets:', function() {
162+
var o = {};
163+
set(o, "a.[b.c.d].e", 'c');
164+
assert.equal(o.a['[b.c.d]'].e, 'c');
165+
});
166+
167+
it('should not split inside parens:', function() {
168+
var o = {};
169+
set(o, "a.(b.c.d).e", 'c');
170+
assert.equal(o.a['(b.c.d)'].e, 'c');
171+
});
172+
173+
it('should not split inside angle brackets:', function() {
174+
var o = {};
175+
set(o, "a.<b.c.d>.e", 'c');
176+
assert.equal(o.a['<b.c.d>'].e, 'c');
177+
});
178+
179+
it('should not split inside curly braces:', function() {
180+
var o = {};
181+
set(o, "a.{b.c.d}.e", 'c');
182+
assert.equal(o.a['{b.c.d}'].e, 'c');
183+
});
184+
185+
it('should not split escaped dots:', function() {
145186
var o = {};
146187
set(o, 'a\\.b.c.d.e', 'c');
147188
assert.equal(o['a.b'].c.d.e, 'c');
148189
});
149190

150-
it('should work with multple escaped dots:', function() {
191+
it('should work with multiple escaped dots:', function() {
151192
var obj1 = {};
152193
set(obj1, 'e\\.f\\.g', 1);
153194
assert.equal(obj1['e.f.g'], 1);

0 commit comments

Comments
 (0)