ldesigns
ldesigns

Reputation: 103

Restructuring Javascript Arrays

EDIT: Thanks for the replies!

I am kind of new to working with Javascript (sorry for probably the bad code). I've mainly only worked with HTML and CSS. I have been trying to experiment with Javascript, but I've been stuck on this forever. The outcome is not what I want it to be.

My code:

I want to make the array easier to use, by putting the values under the same category, but my code's output is not exactly what I want it to be like.

var data = {
  idName: "idName",
  valueRanges: [{
    range: "range",
    majorDimension: "ROWS",
    values: [
      [
        "ID",
        "Category",
        "Name"
      ],
      [
        "1",
        "Category1",
        "Name1"
      ],
      [
        "2",
        "Category1",
        "Name2"
      ],
      [
        "3",
        "Category2",
        "Name3"
      ],
      [
        "4",
        "Category1",
        "Name4"
      ]
    ]
  }]
}

var rows = [];

let batchRowValues = data.valueRanges[0].values
for (let i = 1; i < batchRowValues.length; i++) {
  let rowObject = {};
  for (let j = 0; j < batchRowValues[i].length; j++) {
    rowObject[batchRowValues[0][j]] = batchRowValues[i][j];
  }
  rows.push(rowObject);
}

var newArray = rows.reduce(function(acc, curr) {
  var findIfNameExist = acc.findIndex(function(item) {
    return item.Category === curr.Category;
  })
  if (findIfNameExist === -1) {
    let obj = {
      'Category': curr.Category,
      'value': [curr]
    }
    acc.push(obj)
  } else {
    acc[findIfNameExist].value.push(curr)
  }
  return acc;
}, []);

console.log('------------')
console.log('input: ' + JSON.stringify(data, null, 2))
console.log('------------')
console.log('output: ' + JSON.stringify(newArray, null, 2))

My code's output:

[
  {
    Category: "Category1",
    value: [
      {
        Category: "Category1",
        ID: "1",
        Name: "Name1"
      }, 
      {
        Category: "Category1",
        ID: "2",
        Name: "Name2"
      },
      {
        Category: "Category1",
        ID: "4",
        Name: "Name4"
      }
    ]
  },
  {
    Category: "Category2",
    value: [
      {
        Category: "Category2",
        ID: "3",
        Name: "Name3"
      }
    ]
  }
]

How I want it to look:

[
  {
    Category: "Category1",
    values: [
      {
        ID: "1",
        Name: "Name1"
      },
      {
        ID: "2",
        Name: "Name2"
      },
      {
        ID: "4",
        Name: "Name4"
      }
    ]
  },
  {
    Category: "Category2",
    values: [
      {
        ID: "3",
        Name: "Name3"
      },
    ]
  },
]

I want to learn! I appreciate any help.

Upvotes: 2

Views: 82

Answers (2)

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92337

Try (t={}, result in r)

data.valueRanges[0].values.slice(1).map( ([i,c,n])=> 
    (t[c]=t[c]||{Category:c,values:[]}, t[c].values.push({ID:i, Name:n})) );
let r= Object.values(t);

var data = 
  {
    idName: "idName",
    valueRanges: [
      {
        range: "range",
        majorDimension: "ROWS",
        values: [
          [
            "ID",
            "Category",
            "Name"
          ],
          [
            "1",
            "Category1",
            "Name1"
          ],
          [
            "2",
            "Category1",
            "Name2"
          ],
          [
            "3",
            "Category2",
            "Name3"
          ],
          [
            "4",
            "Category1",
            "Name4"
          ]
        ]
      }
    ]
  }
 
let t={};
data.valueRanges[0].values.slice(1).map( ([i,c,n])=> 
    (t[c]=t[c]||{Category:c,values:[]}, t[c].values.push({ID:i, Name:n})) );
let r= Object.values(t);

console.log(r);

Upvotes: -1

Code Maniac
Code Maniac

Reputation: 37755

You can use reduce.

Here idea is

  • Create a object and use category as key
  • If a category is already found than push the desired object in it's value property. if not than we create a new one with suitable data.

I am using object here instead of array directly is because i can directly access element using key where as in array i need to loop through each time and check existence of value

var data = {idName: "idName",valueRanges: [{range: "range",majorDimension: "ROWS",values: [["ID","Category","Name"],["1","Category1","Name1"],["2","Category1","Name2"],["3","Category2","Name3"],["4","Category1","Name4"]]}]}

var rows = [];
let batchRowValues = data.valueRanges[0].values.slice(1,)

let op = batchRowValues.reduce((op,[ID,Category,Name]) => {
  if( op[Category] ){
    op[Category].value.push({ID,Name})
  } else {
    op[Category] = {
      Category,
      value: [{ID,Name}]
    }
  }
  return op
},{})

console.log(Object.values(op))

Upvotes: 2

Related Questions