1

I'm working with the following data structure:

"data": {
    "products": [
        [
            {
                "category": "A",
                "items": [
                    {
                        "name": "Aloe",
                        "price": 10
                    },
                    {
                        "name": "Apples",
                        "price": 5
                    }
                ]
            },
            {
                "category": "B",
                "items": [
                    {
                        "name": "Bread",
                        "price": 5
                    }
                ]
            }
        ],
        [
            {
                "category": "C",
                "items": [
                    {
                        "name": "Candy",
                        "price": 5
                    },
                    {
                        "name": "Crayon",
                        "price": 5
                    }
                ]
            },
            {
                "category": "D",
                "items": [
                    {
                        "name": "Dice",
                        "price": 5
                    },
                    {
                        "name": "Doll",
                        "price": 10
                    }
                ]
            }
        ]
    ]
}

I'd like extract parts of it to flatten so the results is as follows:

[
    {
        "name": "Aloe",
        "price": 10
    },
    {
        "name": "Apples",
        "price": 5
    },
    {
        "name": "Bread",
        "price": 5
    },
    {
        "name": "Candy",
        "price": 5
    },
    {
        "name": "Crayon",
        "price": 5
    },
    {
        "name": "Dice",
        "price": 5
    },
    {
        "name": "Doll",
        "price": 10
    }
]

How can I accomplish this?

I have tried this:

for (var sets in data.products) {
  for (var categories in sets) {
    for (var items in categories) {
      for (var item in items) { 
        // assemble new array 
      }
    }
  }
}

... but had problems looping through the children objects. I've found a couple other similar questions, but they seem to address simpler data structures, and flatten the entire object rather than parts of it.

Any pointers would be appreciated.

Krush
  • 27
  • 5

5 Answers5

1
input.data.products. ....

maube Change in row 1 depend on your variable name

var result =[]
input.data.products.forEach(function (product){
    product.forEach(function(productinfo){
      productinfo.items.forEach(function (item){


          result.push(item)


      })

    })

})
Nozar Safari
  • 505
  • 4
  • 17
0

You will have to try something like this:

Logic:

  • Loop over data.products to get individual product details.
  • Sine details are also arrays, loop over them and return items from them.

The trick is, you will have to use Array.prototype.concat to merge arrays returned, to flatten them.

var data = {
  "products": [
    [{
        "category": "A",
        "items": [{
            "name": "Aloe",
            "price": 10
          },
          {
            "name": "Apples",
            "price": 5
          }
        ]
      },
      {
        "category": "B",
        "items": [{
          "name": "Bread",
          "price": 5
        }]
      }
    ],
    [{
        "category": "C",
        "items": [{
            "name": "Candy",
            "price": 5
          },
          {
            "name": "Crayon",
            "price": 5
          }
        ]
      },
      {
        "category": "D",
        "items": [{
            "name": "Dice",
            "price": 5
          },
          {
            "name": "Doll",
            "price": 10
          }
        ]
      }
    ]
  ]
}

var result = [].concat.apply([], data.products.map(function(product){
  return [].concat.apply([], product.map(function(p){
    return p.items
  }))
}))

console.log(result)
Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • Hey Rajesh, in response to your previous comment (now deleted), I have tried some stuff, and the looping part is where I was having problems: `for (var sets in data.products) { for (var categories in sets) { for (var items in categories) { for (var item in items) { // assemble new array } } } }` – Krush Nov 16 '17 at 07:26
  • @P.Krush Adding your effort helps us to understand how far you have reached and how much further you want to go to achieve your goal. We can also point out corrections/ improvements. Just saying *I have this input and want to achieve this* makes the question a requirement. Your effort is what makes it a problem statement. So remember to share it **in question** in future. – Rajesh Nov 16 '17 at 07:33
0

I have assigned your JSON object for data to a variable first. See the code below:

var pro={
    "products": [
        [
            {
                "category": "A",
                "items": [
                    {
                        "name": "Aloe",
                        "price": 10
                    },
                    {
                        "name": "Apples",
                        "price": 5
                    }
                ]
            },
            {
                "category": "B",
                "items": [
                    {
                        "name": "Bread",
                        "price": 5
                    }
                ]
            }
        ],
        [
            {
                "category": "C",
                "items": [
                    {
                        "name": "Candy",
                        "price": 5
                    },
                    {
                        "name": "Crayon",
                        "price": 5
                    }
                ]
            },
            {
                "category": "D",
                "items": [
                    {
                        "name": "Dice",
                        "price": 5
                    },
                    {
                        "name": "Doll",
                        "price": 10
                    }
                ]
            }
        ]
    ]
}
var flatArray=[];
for(var i=0; i<pro.products.length; i++){
  for(var j=0; j<pro.products[i].length;j++){
    for(var k=0; k<pro.products[i][j].items.length;k++){
      flatArray.push(pro.products[i][j].items[k]);
    }
  }
}

The flatArray will be your required flattened array of objects. Hope this is clear enough.

vishal kokate
  • 126
  • 3
  • 12
0

You can use array#reduce, array#forEach and array#concat.

var input =  { data: { products: [[{ category: "A", items: [{ name: "Aloe", price: 10 }, { name: "Apples", price: 5 }] }, { category: "B", items: [{ name: "Bread", price: 5 }] }], [{ category: "C", items: [{ name: "Candy", price: 5 }, { name: "Crayon", price: 5 }] }, { category: "D", items: [{ name: "Dice", price: 5 }, { name: "Doll", price: 10 }] }]] } };

const result = input.data.products.reduce((res, arr) => {
  arr.forEach( o => res = res.concat(o.items));
  return res;
},[]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Hassan Imam
  • 21,956
  • 5
  • 41
  • 51
0

You could use a recursive approach by checking the items property or return the result of reduced properties. This approach works for any depth with an expected items property at the end.

function flat(object) {
    return object.items || Object.keys(object).reduce(function (r, k) {
        return r.concat(flat(object[k]));
    }, []);
}

var object = { data: { products: [[{ category: "A", items: [{ name: "Aloe", price: 10 }, { name: "Apples", price: 5 }] }, { category: "B", items: [{ name: "Bread", price: 5 }] }], [{ category: "C", items: [{ name: "Candy", price: 5 }, { name: "Crayon", price: 5 }] }, { category: "D", items: [{ name: "Dice", price: 5 }, { name: "Doll", price: 10 }] }]] } }

console.log(flat(object));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392