File size: 2,377 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import * as is from '../is';
import { extend } from './extend';

  // has anything been set in the map
export const mapEmpty = map => {
  let empty = true;

  if( map != null ){
    return Object.keys( map ).length === 0;
  }

  return empty;
};

// pushes to the array at the end of a map (map may not be built)
export const pushMap = options => {
  let array = getMap( options );

  if( array == null ){ // if empty, put initial array
    setMap( extend( {}, options, {
      value: [ options.value ]
    } ) );
  } else {
    array.push( options.value );
  }
};

// sets the value in a map (map may not be built)
export const setMap = options => {
  let obj = options.map;
  let keys = options.keys;
  let l = keys.length;

  for( let i = 0; i < l; i++ ){
    let key = keys[ i ];

    if( is.plainObject( key ) ){
      throw Error( 'Tried to set map with object key' );
    }

    if( i < keys.length - 1 ){

      // extend the map if necessary
      if( obj[ key ] == null ){
        obj[ key ] = {};
      }

      obj = obj[ key ];
    } else {
      // set the value
      obj[ key ] = options.value;
    }
  }
};

// gets the value in a map even if it's not built in places
export const getMap = options => {
  let obj = options.map;
  let keys = options.keys;
  let l = keys.length;

  for( let i = 0; i < l; i++ ){
    let key = keys[ i ];

    if( is.plainObject( key ) ){
      throw Error( 'Tried to get map with object key' );
    }

    obj = obj[ key ];

    if( obj == null ){
      return obj;
    }
  }

  return obj;
};

// deletes the entry in the map
export const deleteMap = options => {
  let obj = options.map;
  let keys = options.keys;
  let l = keys.length;
  let keepChildren = options.keepChildren;

  for( let i = 0; i < l; i++ ){
    let key = keys[ i ];

    if( is.plainObject( key ) ){
      throw Error( 'Tried to delete map with object key' );
    }

    let lastKey = i === options.keys.length - 1;
    if( lastKey ){

      if( keepChildren ){ // then only delete child fields not in keepChildren
        let children = Object.keys( obj );

        for( let j = 0; j < children.length; j++ ){
          let child = children[j];

          if( !keepChildren[ child ] ){
            obj[ child ] = undefined;
          }
        }
      } else {
        obj[ key ] = undefined;
      }

    } else {
      obj = obj[ key ];
    }
  }
};