Javascript объект, вернуть обновленный объект, который содержит значение во вложенных массивах - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть следующий объект:

{
  "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 'в противном случае массив не должен содержать этот ключ в массиве ключей.

Ожидаемый результат:

{
  "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 голосов
/ 08 февраля 2019

Вывод функции, заданной для 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, поэтому фильтр снова сохранит только те категории, которые все еще содержат ключи.

0 голосов
/ 08 февраля 2019

Вы можете использовать вложенный подход и уменьшить массив, проверив вложенный массив filterd.

Это решение не изменяет исходные данные.

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; }
0 голосов
/ 08 февраля 2019

Надеюсь, это работает для вас.

Кроме того, фильтр не является методом на месте, поэтому, даже если вы фильтруете 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)
...