skip to Main Content

I have a array of objects

  • Some objects have id and some are not
  • those having id can present with either "split" or "relation" key not both
  • inside split there can be another split or relation
  • now I need to read all relation present by digging deeply

I need output like below:

let _rel = [
    {"relation": "a"},
    {"relation": "b"}
]
// my try which is not working 
const getRelations = (arr, _rel=[]) => {
    for(let {uuid, relations, split} of arr){
        if(uuid) {
            if(relations) [..._rel, relations]
            else if(split) {
                getRelations(split)
            }
        }
    }
    return _rel    
}
getRelations(arr)

Input:

let arr = [
            {"start_offset": 0},
            {
                "uuid": "100",
                "relations": [
                    {
                        "relation": "a",
                    }
                ]            
            },
            {"start_offset": 355},
            {
                "uuid": "200",
                "split": [
                    {
                        "uuid": "300",
                        "split": [
                            {
                                "uuid": "400",
                                "relations": [
                                    {
                                        "relation": "b",
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "uuid": "500",
                    }
                ],
            },
            {"start_offset": 689}
]

// my try which is not working 
const getRelations = (arr, _rel=[]) => {
    for(let {uuid, relations, split} of arr){
        if(uuid) {
            if(relations) [..._rel, relations]
            else if(split) {
                getRelations(split)
            }
        }
    }
    return _rel    
}
getRelations(arr)

4

Answers


  1. You need to assign the result of the spread operation to _rel when you have relations in order to accumulate the values.
    When you recursively call getRelations(split), you should merge the results with _rel.

    EDIT
    Pure javascript (wrong react)

    You can make sure the function works with arrays of any type by using a generic parameter

    const getRelations = (arr, _rel = []) => {
        for (let { uuid, relations, split } of arr) {
            if (uuid) {
                if (relations) {
                    _rel.push(...relations);
                } else if (split) {
                    getRelations(split, _rel);
                }
            }
        }
        return _rel;
    };
    
    const arr = [
        { "start_offset": 0 },
        {
            "uuid": "100",
            "relations": [
                {
                    "relation": "a",
                }
            ]
        },
        { "start_offset": 355 },
        {
            "uuid": "200",
            "split": [
                {
                    "uuid": "300",
                    "split": [
                        {
                            "uuid": "400",
                            "relations": [
                                {
                                    "relation": "b",
                                }
                            ]
                        }
                    ]
                },
                {
                    "uuid": "500",
                }
            ]
        },
        { "start_offset": 689 }
    ];
    
    const result = getRelations(arr);
    console.log(result);
    
    Login or Signup to reply.
  2. You could take a check and return a flat array of relations or an empty array.

    const
        data = [{ start_offset: 0 }, { uuid: "100", relations: [{ relation: "a" }] }, { start_offset: 355 }, { uuid: "200", split: [{ uuid: "300", split: [{ uuid: "400", relations: [{ relation: "b" }] }] }, { uuid: "500" }] }, { start_offset: 689 }],
        fn = ({ split, relations }) => split
            ? split.flatMap(fn)
            : relations || [],
        getRelations = array => array.flatMap(fn);
    
    console.log(getRelations(data));
    Login or Signup to reply.
  3. A couple of changes:

    1- When you have relations, push the { "relation": relations }
    object into the _rel array.

    2- When you have split, recursively call getRelations with the split array and pass the existing _rel array.

    Now, the relations array should be correctly populated with the desired output.

    const getRelations = (arr, _rel = []) => {
      for (let {
          uuid,
          relations,
          split
        } of arr) {
        if (uuid) {
          if (relations) {
            _rel.push({
              "relation": relations
            });
          } else if (split) {
            getRelations(split, _rel);
          }
        }
      }
      return _rel;
    };
    
    
    const arr = [{
        uuid: "1",
        relations: "a",
        split: [{
          uuid: "2",
          relations: "b"
        }]
      },
      {
        uuid: "3",
        split: [{
          uuid: "4",
          relations: "c"
        }]
      },
    ];
    
    const relations = getRelations(arr);
    console.log(relations);
    Login or Signup to reply.
  4. An one-liner:

    const data = [{ start_offset: 0 }, { uuid: "100", relations: [{ relation: "a" }] }, { start_offset: 355 }, { uuid: "200", split: [{ uuid: "300", split: [{ uuid: "400", relations: [{ relation: "b" }] }] }, { uuid: "500" }] }, { start_offset: 689 }];
    
    const getRelations = (items, out = []) => (items.forEach(item => item.split ? getRelations(item.split, out) : item.relations && out.push(...item.relations)), out);
    
    console.log(getRelations(data));
    ` Chrome/119
    -----------------------------------------------------------
    Alexander      1.00x  |  x10000000  567  571  573  589  590
    Nina Scholz   11.09x  |   x1000000  629  630  633  648  659
    -----------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    const data = [{ start_offset: 0 }, { uuid: "100", relations: [{ relation: "a" }] }, { start_offset: 355 }, { uuid: "200", split: [{ uuid: "300", split: [{ uuid: "400", relations: [{ relation: "b" }] }] }, { uuid: "500" }] }, { start_offset: 689 }];
    
    //@benchmark Nina Scholz
    
    const fn = ({ split, relations }) => split
            ? split.flatMap(fn)
            : relations || [],
        getRelations = array => array.flatMap(fn);
    
    getRelations(data);
    
    
    //@benchmark Alexander 
    {
    const getRelations = (items, out = []) => (items.forEach(item => item.split ? getRelations(item.split, out) : item.relations && out.push(...item.relations)), out);
    getRelations(data);
    
    }
    
    
    /*@end*/eval(atob('e2xldCBlPWRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3Rvcigic2NyaXB0Iik7aWYoIWUubWF0Y2hlcygiW2JlbmNobWFya10iKSl7bGV0IHQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7dC5zcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9naC9zaWxlbnRtYW50cmEvYmVuY2htYXJrL2xvYWRlci5qcyIsdC5kZWZlcj0hMCxkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHQpfX0='));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search