1

In the below JSON structure,

[
  {
    "type": "heading-1",
    "text": "A title",
  },
  {
    "type": "ordered-list-item",
    "text": "Ordered Item A",
  },
  {
    "type": "unordered-list-item",
    "text": "Ordered Item B",
  },
  {
    "type": "heading-2",
    "text": "A title",
  },
  {
    "type": "ordered-list-item",
    "text": "Ordered Item A",
  },
  {
    "type": "unordered-list-item",
    "text": "Ordered Item B",
  }
];

I need to move all the type which as ordered-list-item & unordered-list-item into new object. Something like below,

  {
    "type": 'list',
    "items": [
      {
        "type": "ordered-list-item",
        "text": "Ordered Item A",
      },
      {
        "type": "unordered-list-item",
        "text": "Ordered Item B",
      }
    ]
  }

Most important is, I need to maintain the order

For example, ordered-list-item & unordered-list-item should be pushed inside new object until the type is matched.

So with the above Json structure, Below is the expected output

[
  {
    "type": "heading-1",
    "text": "A title",
  },
  {
    "type": "heading-2",
    "text": "A title",
  },
  {
    "type": 'list',
    "items": [
      {
        "type": "ordered-list-item",
        "text": "Ordered Item A",
      },
      {
        "type": "unordered-list-item",
        "text": "Ordered Item B",
      }
    ]
  },
  {
    "type": "heading-1",
    "text": "A title",
  },
  {
    "type": 'list',
    "items": [
      {
        "type": "ordered-list-item",
        "text": "Ordered Item A",
      },
      {
        "type": "unordered-list-item",
        "text": "Ordered Item B",
      }
    ]
  },
]

How can this be done ?

2

2 Answers 2

1

You can use array.filter on any array to create a new array matching the criteria (in the same order)

const orderedList = yourArray.filter(a => a.type === 'ordered-list-item');
const unOrderedList = yourArray.filter(a => a.type === 'unordered-list-item');

then just build up the new json object using your new filtered array(s).

Sign up to request clarification or add additional context in comments.

Comments

0
function deconstruct(data) {
    let index = -1;
    const out = [];

    data.forEach(entry => {
        if (entry.type !== 'ordered-list-item' && entry.type !== 'unordered-list-item') {
            // If the current entry's type prop is no (un)ordered-list-item
            // We push it to the array and reset the index variable to -1
            out.push(entry);
            index = -1;
        } else {
            // Else, we check if index is -1. If it is, we push a new object
            // And save its index to the index variable
            if (index === -1) {
                index = out.push({ type: 'list', items: [] }) - 1;
            }

            // Add the entry to the items of the current list
            out[index].items.push(entry);
        }
    });

    return out;
}

Here's another way of doing it:

data.map((entry, index) => {
  return {...entry, index, use: entry.type !== 'unordered-list-item' && entry.type !== 'ordered-list-item'}
}).filter(entry => entry.use).map((entry, index, entries) => {
  const end = index < entries.length -1 ? entries[index + 1].index : data.length - entry.index;
  return [{type: entry.type, text: entry.text}, {type: 'list', items: data.slice(entry.index + 1, entry.index + end)}]
}).flat(2);

8 Comments

filter functions are made for this kind of task.
Right. However, if you read the question in its entirety, a simple .filter will not suffice.
@TimVN - I tried your method it throws an error, can you check this link stackblitz.com/edit/typescript-55jywf?file=index.ts
Does not throw an error for me, take a look: jsfiddle.net/2gjyrxkq
My data structure as been changed, I tired the solution which you've provided got a error not able to resolve it. Can you check stackblitz stackblitz.com/edit/typescript-55jywf?file=index.ts
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.