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 ?

stack s
  • 109
  • 13
  • 3
    why do you have two headings at start and later again? what have you tried? btw, [JSON](http://json.org) is a stringified object. – Nina Scholz Apr 29 '19 at 12:33
  • Please learn [the difference between JSON and Object Literal Notation](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation). – str Apr 29 '19 at 12:57

2 Answers2

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

Tree Frog
  • 637
  • 5
  • 12
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);
Tim VN
  • 1,183
  • 1
  • 7
  • 19
  • filter functions are made for this kind of task. – Marco Apr 29 '19 at 12:57
  • Right. However, if you read the question in its entirety, a simple ```.filter``` will not suffice. – Tim VN Apr 29 '19 at 13:00
  • @TimVN - I tried your method it throws an error, can you check this link https://stackblitz.com/edit/typescript-55jywf?file=index.ts – stack s Apr 30 '19 at 05:35
  • Does not throw an error for me, take a look: https://jsfiddle.net/2gjyrxkq/ – Tim VN Apr 30 '19 at 08:32
  • 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 https://stackblitz.com/edit/typescript-55jywf?file=index.ts – stack s Apr 30 '19 at 08:40
  • Is the expected outcome still the same, then? Cause this looks already somewhat ordered. – Tim VN Apr 30 '19 at 09:19
  • Its throws an error `data.slice is not a function` https://stackblitz.com/edit/typescript-55jywf?file=index.ts – stack s Apr 30 '19 at 09:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192623/discussion-between-tim-vn-and-stack-s). – Tim VN Apr 30 '19 at 09:48