Javascript对象,返回包含嵌套数组中的值的更新对象

时间:2019-02-08 11:37:52

标签: javascript arrays json object filter

我有以下对象:

{
  "id": 2,
  "name": "tes name",
  "status": 0,
  "categories": [
    {
      "category_id": 1,
      "name": "taxes",
      "description": "taxes",
      "keys": [
        {
          "key_id": 1,
          "value": "preset unique value if not overridden, real text value"
        },
        {
          "key_id": 2,
          "value": "test name"
        }
      ]
    },
    {
      "category_id": 2,
      "name": "surcharges",
      "description": "surcharges",
      "keys": [
        {
          "key_id": 3,
          "value": "preset value if not overridden, real text value"
        },
        {
          "key_id": 5,
          "value": ""
        }
      ]
    },
    {
      "category_id": 3,
      "name": "errors",
      "description": "errors",
      "keys": [
        {
          "key_id": 6,
          "value": "preset value if not overridden, real text value"
        },
        {
          "key_id": 10,
          "value": "unique value to test search"
        }
      ]
    }
  ]
}

我需要做的是基于更新对象:如果只有key.value包含字符串' unique ',则它必须在keys数组中包含键,否则数组不能包含该键在keys数组中。

预期输出为:

{
  "id": 2,
  "name": "tes name",
  "status": 0,
  "categories": [
    {
      "category_id": 1,
      "name": "taxes",
      "description": "taxes",
      "keys": [
        {
          "key_id": 1,
          "value": "preset unique value if not overridden, real text value"
        }
      ]
    },
    {
      "category_id": 3,
      "name": "errors",
      "description": "errors",
      "keys": [
        {
          "key_id": 10,
          "value": "unique value to test search"
        }
      ]
    }
  ]
}

我尝试了嵌套过滤器,但它对我不起作用,总是得到与原来相同的对象。

我的代码:

var result = obj.categories.filter(function(category) {
    return category.keys.filter(function(key) {
        return key.value.includes(action.payload)
    });
});

有什么建议或我哪里出问题了?

3 个答案:

答案 0 :(得分:1)

您可以采用嵌套方法,并通过检查嵌套的过滤数组来缩小数组。

此解决方案不会变异原始数据。

var data = { id: 2, name: "tes name", status: 0, categories: [{ category_id: 1, name: "taxes", description: "taxes", keys: [{ key_id: 1, value: "preset unique value if not overridden, real text value" }, { key_id: 2, value: "test name" }] }, { category_id: 2, name: "surcharges", description: "surcharges", keys: [{ key_id: 3, value: "preset value if not overridden, real text value" }, { key_id: 5, value: "" }] }, { category_id: 3, name: "errors", description: "errors", keys: [{ key_id: 6, value: "preset value if not overridden, real text value" }, { key_id: 10, value: "unique value to test search" }] }] },
    filtered = Object.assign({}, data, {
        categories: data.categories.reduce((r, o) => {
            var keys = o.keys.filter(({ value }) => value.includes('unique'));
            if (keys.length) {
                r.push(Object.assign({}, o, { keys }));
            }
            return r;
        }, [])
    });

console.log(filtered);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

希望这对您有用。

过滤器也不是就位方法,因此即使您正在过滤Categories.keys并返回它,也不会对其进行修改。

一旦过滤,我们将使用category.keys.length过滤具有空键的类别

var obj = {
  "id": 2,
  "name": "tes name",
  "status": 0,
  "categories": [
    {
      "category_id": 1,
      "name": "taxes",
      "description": "taxes",
      "keys": [
        {
          "key_id": 1,
          "value": "preset unique value if not overridden, real text value"
        },
        {
          "key_id": 2,
          "value": "test name"
        }
      ]
    },
    {
      "category_id": 2,
      "name": "surcharges",
      "description": "surcharges",
      "keys": [
        {
          "key_id": 3,
          "value": "preset value if not overridden, real text value"
        },
        {
          "key_id": 5,
          "value": ""
        }
      ]
    },
    {
      "category_id": 3,
      "name": "errors",
      "description": "errors",
      "keys": [
        {
          "key_id": 6,
          "value": "preset value if not overridden, real text value"
        },
        {
          "key_id": 10,
          "value": "unique value to test search"
        }
      ]
    }
  ]
}

var result = obj.categories.filter(function(category) {
      category['keys']=category.keys.filter(function(key) {
       return key.value.includes('unique')
    })
    return category['keys'].length
});

console.log(result)

答案 2 :(得分:0)

提供给filter()的函数的输出应始终返回一个布尔值,该布尔值指示是否应滤除该值。您的代码

return category.keys.filter(function(key) {
    return key.value.includes(action.payload)
});

返回已过滤的键列表,但是外部过滤器功能将这些列表用作过滤器值。只要过滤后的列表包含任何元素,它将被转换为true,因此类别不会被过滤掉。

实际代码应该看起来像这样:

obj.categories.forEach(function(category){
    category.keys = category.keys.filter(function(key){
        return key.value.includes(action.payload);
    });
});

这会遍历所有键数组,并将过滤器应用于每个键数组。

如果您还想过滤掉具有空键数组的类别,则可以重新添加外部过滤器,但将分配保留到category.keys

obj.categories = obj.categories.filter(function(category){
    return (category.keys = category.keys.filter(function(key){
        return key.value.includes(action.payload);
    }););
});

之所以可行,是因为分配的返回值是分配给category.keys的值,因此过滤器将再次仅保留那些仍包含键的类别。