根据对象的属性数组查找数组

时间:2021-04-20 08:03:38

标签: javascript arrays

我试图根据对象数组的元素 id 获取一个数组,其结构如下所示

{"data": [
        {
            "id": 46,
            "name": "shsjks",
            "desc": "ehejej",
            "code": "hshsbsb",
            "activation_type": 1,
            "detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",
        },
        {
            "id": 47,
            "name": "hhksns",
            "desc": "benemne",
            "code": "gevewk",
            "activation_type": 1,
            "detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"
        },
    ]}

我正在尝试根据详细信息 ID 和我所做的事情获取数据

let arr = a.data.filter(x => {
    return (JSON.parse(x.detail).filter(x => x.id === 419))
});
// returned all instead of first element of the array

我想退货

// filter where id 419
{
  "id": 47,
  "name": "shjks",
  "detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"
  ....
}

3 个答案:

答案 0 :(得分:1)

.filter 不会执行映射。其回调函数的返回值应该只是指示是否应包含数组元素(来自顶级数组)。因此,当您不希望包含数组时,您应该返回一个假值。由于 .some 返回一个布尔值,这是用于该目的的完美候选方法。如果您只希望匹配一次,那么 .find.filter 更合适:

let a = {"data": [{"id": 46,"name": "shsjks","desc": "ehejej","code": "hshsbsb","activation_type": 1,"detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",},{"id": 47,"name": "hhksns","desc": "benemne","code": "gevewk","activation_type": 1,"detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"},]}

let result = a.data.find(x => JSON.parse(x.detail).some(x => x.id === 419));

console.log(result);

如果您希望 details 在结果中保持解析状态,请先执行 map

let a = {"data": [{"id": 46,"name": "shsjks","desc": "ehejej","code": "hshsbsb","activation_type": 1,"detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",},{"id": 47,"name": "hhksns","desc": "benemne","code": "gevewk","activation_type": 1,"detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"},]}

let result = a.data.map(x => ({ ...x, detail: JSON.parse(x.detail)}))
                   .find(x => x.detail.some(x => x.id === 419));

console.log(result);

如果你只对 id 键本身感兴趣,那么执行一次 .flatMap 来首先收集所有解析过的 detail 数组,这样你就会得到一个包含所有细节的数组,然后.find 您需要的元素:

let a = {"data": [{"id": 46,"name": "shsjks","desc": "ehejej","code": "hshsbsb","activation_type": 1,"detail": "[{\"id\": 413, \"name\": \"A\"}, {\"id\": 416, \"name\": \"B\"}]",},{"id": 47,"name": "hhksns","desc": "benemne","code": "gevewk","activation_type": 1,"detail": "[{\"id\": 419, \"name\": \"C\"}, {\"id\": 423, \"name\": \"D\"}]"},]}

let result = a.data.flatMap(x => JSON.parse(x.detail)).find(x => x.id === 419);

console.log(result);

答案 1 :(得分:0)

你应该做这样的事情。

let arr = a.data.filter(x => {
    return (JSON.parse(x.detail).filter(x => x.id === 419).length)
});

Array.filter 返回 [] 如果没有值存在。所以当你返回数组本身时,它永远不会被认为是假的。

答案 2 :(得分:0)

您代码中的问题是第一个过滤器需要返回一个布尔值(过滤器与否)

这对你有用:

const test = {
  data: [
    {
      id: 46,
      name: 'shsjks',
      desc: 'ehejej',
      code: 'hshsbsb',
      activation_type: 1,
      detail: '[{"id": 413, "name": "A"}, {"id": 416, "name": "B"}]',
    },
    {
      id: 47,
      name: 'hhksns',
      desc: 'benemne',
      code: 'gevewk',
      activation_type: 1,
      detail: '[{"id": 419, "name": "C"}, {"id": 423, "name": "D"}]',
    },
  ],
};

const arr = test.data.find((x) => JSON.parse(x.detail).some((d) => d.id === 419));

console.log(JSON.stringify(arr, null, 2));

相关问题