如何基于数组构建自定义对象选择器

时间:2017-06-10 20:26:43

标签: javascript angularjs

我有一个像这样的数组跟踪父对象的类似:

var object = {
 'Shirt': {
    'Color':'Blue',
    'Size':'Large'
  },
  'Pants': {
    'Color':'White',
    'Size':'Medium',
  }
}

我正在编写一个实时对象操作类型的东西,并且正在跟踪它们所在的对象。该数组如下所示:

var objectPath = ['Shirt', 'Color'];

现在我需要使用该数组来创建一个选择器,它允许我操纵对象路径中的数据,最终得到类似的东西。

selector = object['Shirt']['Color'];

我可以这样做:selector = 'Yellow'它会改变对象中的相应选择。

我尝试了这个,但我无法将数组转换为选择器:

objectPath.forEach(function(path, i) {
  selector += '[path]';
});

我知道我正在创建一个新的字符串,我无法弄清楚如何使用eval或类似的东西来做这件事。

2 个答案:

答案 0 :(得分:3)

let obj = {
  'shirt': {
   'color': 'blue'
   }
},
ref = obj,
selectors = ['shirt', 'color']
newValue = 'yellow';
selectors.forEach(  (selector, index) => {
   if(index === selectors.length - 1) ref[selector] = newValue
   else ref = ref[selector];
})
console.log(obj.shirt.color)

如果你想操纵原始对象,你需要在最终属性之前建立路径,然后将该属性设置为新值。

答案 1 :(得分:2)

你可以Array.prototype.reduce在每个'路径'迭代上获得下一个嵌套级别:

const data = {
  one: {
    two: {
      three: {
        four: 'five'
     }
    }
  }
}

const path = ['one', 'two', 'three', 'four']

const value = path.reduce((a, v) => a[v], data);

console.log(value)

你甚至可以创建一个接受'path'数组和对象的函数,如果路径错误则返回一个值或'null':

// function
const objSelector = o => pathArr => (Array.isArray(pathArr)) 
    ? pathArr.reduce((a, c) => (a[c] != null) ? a[c] : null, o)
    : null;

const data = {
  one: {
    two: {
      three: {
        four: 'five'
     }
    }
  }
}

const path = ['one', 'two', 'three', 'four']

// use function
const value = objSelector(data)(path)

console.log(value)