在嵌套对象数组的任何级别中查找任何值?

时间:2015-10-04 00:31:58

标签: javascript

我有一组嵌套对象

var arr = [{
  tires: 2,
  exterior: {
    color: 'white',
    length: 2,
    width: 1
  }
},{
  tires: 4,
  exterior: {
    color: 'blue',
    length: 5,
    width: 3
  }
},{
  tires: 4,
  exterior: {
    color: 'white',
    length: 2,
    width: 3
  }
}];

我想创建一个函数:

var findItems = function(arr, value){
  // return array of found items
};

一些例子:

findItems(arr, 'white');                    // [ arr[0], arr[2] ]
findItems(arr, 2);                          // [ arr[0], arr[2] ]
findItems(arr, {tires: 2});                 // [ arr[0] ]
findItems(arr, {tires: 2, color: 'white'}); // [  ]
findItems(arr, {width: 1, color: 'white'}); // [ arr[0] ]

很容易找到具有非嵌套对象的数组的值,或者如果您知道要搜索的确切级别。但我不知道如何在一个地方找到“任何值,任何地方”阵列。我很快就陷入了地狱。

如果有帮助,我可以使用Underscore。

1 个答案:

答案 0 :(得分:1)

我认为会是这样的:

function isObject(val) {
  return Object(val) === val;
}
function search(val, ctx) {
  var valIsObject = isObject(val);
  return (function search(context) {
    if(!isObject(context)) return val === context;
    if(valIsObject && Object.keys(val).every(function(key) {
      return context[key] === val[key];
    })) return true;
    return Object.keys(context).some(function(key) {
      return search(context[key]);
    });
  })(ctx);
}
function findItems(arr, value){
  return arr.filter(function(item) {
    return search(value, item);
  });
}

它应该工作得相当好,除了在一些边缘情况下,如循环引用(无限递归)或描述符属性(代码可能在不兼容的对象上调用getter)。