简体   繁体   中英

find an array based on its property array of object

im trying to get an array based on its element id of array of object and the structure is looks like this

{"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\"}]"
        },
    ]}

im trying to get the data based on the detail id and what i did

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

i want it to returned

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

.filter will not perform a map. The return value of its callback function is supposed to just indicate whether the array element (from the top level array) should be included or not. So you should return a falsy value when you don't want an array to be included. As .some returns a boolean, that is a perfect candidate method to use for that purpose. And if you expect only one match, then .find is more appropriate than .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);

If you want the details to remain parsed in the result, then first perform a 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);

If you are only interested in the id key itself, then perform a .flatMap to first collect all parsed detail arrays, so you get one array with all the details, and then .find the element you need:

 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);

You should do something like this.

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

Array.filter returns [] if there is no value present. So when you return the array itself it is never considered as false.

The problem in your code is that the first filter need to return a boolean value (filter or not)

This will work for u:

 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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM