3

我有一些格式如下的 JSON 数据:

{
    "id": "ABC123",
    "offerPrice": 42.00,
    "regularPrice": 42.00,
    "variations": [{
        "key": "Style",
        "value": "Black"
    }, {
        "key": "Personalization",
        "value": "2 Lines of Personalization"
    }]
}, {
    "id": "987ZYX",
    "offerPrice": 52.00,
    "regularPrice": 52.00,
    "variations": [{
        "key": "Style",
        "value": "Black"
    }, {
        "key": "Personalization",
        "value": "3 Lines of Personalization"
    }]
}

我需要做的是查询'variations'数组中的值,如果找到匹配则返回对象。

我可以很好地查询值的“第一级”:

var results = jQuery.grep(obj, function (element, index) {
    return element.offerPrice == "42.00";
});

如果我指定一个索引值(我显然不想这样做),我可以查询变化:

var results = jQuery.grep(obj, function (element, index) {
    return element.variations[1].key == "Personalization" && element.variations[1].value == "2 Lines of Personalization";
});

理想情况下,这是我想要做的,但它不起作用:

var results = jQuery.grep(obj.variations, function (element, index) {
    return element.key == "Personalization" && element.value == "2 Lines of Personalization";
});

我不断得到:

Uncaught TypeError: Cannot read property 'length' of undefined

这是一个 jsFiddle:http: //jsfiddle.net/VzqWW/3/

有任何想法吗?

4

5 回答 5

3

没有这样的对象,obj.variations因为 obj 是一个数组。像这样的东西应该工作:

var results = jQuery.grep(obj, function (element, index) {
    res = jQuery.grep(element.variations, function (element2, index2) {
        return element2.key== "Personalization" && element2.value == "2 Lines of Personalization";
    });
    return (res.length != 0);
});
于 2013-03-07T23:11:47.347 回答
1

map您可以使用作为 ES5 一部分的( link )、reduce( link ) 和filter( link ) 方法的标准数组过滤来做到这一点,我已经更新了jsfiddle以使用它们,但代码在下面内联:

var variations = obj.map(function (x) { 
    return x.variations;
}).reduce(function (x, y) {
   return x.concat(y); 
});

var personalizationVariations = variations.filter(function (v) {
    return v.key== "Personalization" && v.value == "2 Lines of Personalization"
});
console.log('Personalization Variations', personalizationVariations);

如果您支持 ES3 浏览器 (< IE9),您将需要像es5shim这样添加这些方法的东西。

于 2013-03-07T23:12:06.027 回答
1

使用jQuery.map和 grep怎么样?

var allVariations = $.map(obj, function(element, i) {
    return element.variations;
});

var variations = $.grep(allVariations, function(variation, index) {
    return variation.key == "Personalization" && variation.value == "2 Lines of Personalization";
});
于 2013-03-07T23:39:24.193 回答
0

这对我有用。

var obj=[{
    "id": "ABC123",
    "offerPrice": 42.00,
    "regularPrice": 42.00,
    "variations": [{
        "key": "Style",
        "value": "Black"
    }, {
        "key": "Personalization",
        "value": "2 Lines of Personalization"
    }]
}, {
    "id": "987ZYX",
    "offerPrice": 52.00,
    "regularPrice": 52.00,
    "variations": [{
        "key": "Style",
        "value": "Black"
    }, {
        "key": "Personalization",
        "value": "3 Lines of Personalization"
    }]
}];
var result=$.grep(obj,function(element,index){
    return element.offerPrice=="42.00";
});
var variations=$.grep(result[0].variations, function(element, index){
    return element.key == "Personalization" && element.value == "2 Lines of Personalization";
});
于 2013-03-07T23:19:27.627 回答
0

在 ES5 中你可以这样写:

var filtered = obj.filter(function(el){
  return el.variations.some(function(el) {
    return el.key === "Personalization" && el.value === "2 Lines of Personalization";
  })
});

console.log(filtered);

您可以grep在 jQuery 中使用来模拟filter,但据我所知,它没有类似some. 当然你也可以模仿。您还可以在 MDN 中找到filter的 shim和一些。

一般来说,如果我们想支持旧版浏览器,为 ES5 功能添加一个 shim 总是好的。

于 2013-03-07T23:29:21.953 回答