如何将对象数组转换为嵌套对象数组?

时间:2019-07-14 06:02:37

标签: javascript arrays

我有一个具有以下结构的对象数组:

var items = [
  {
    attributes: [
      {
        type: "Size",
        value: "Small"
      },
      {
        type: "Color",
        value: "Black"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Small"
      },
      {
        type: "Color",
        value: "White"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Medium"
      },
      {
        type: "Color",
        value: "Black"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Medium"
      },
      {
        type: "Color",
        value: "White"
      }
    ]
  }
];

我的目标是提取具有相同“类型” 的所有“值” 属性。例如,类型“大小” 具有以下值:小,中。之后,我要创建一个具有以下结构的新列表:

 var results = [
  {
    type: "Size",
    values: ["Small", "Medium"]
  },
  {
    type: "Color",
    values: ["White", "Black"]
  }
];

这是我当前的代码:

var results = items.map((item, index) => {
  return item.attributes.map(attribute => {
    let value = [];
    value.push(attribute.value);
    return {
      type: attribute.type,
      value: attribute.value
    };
  });
});

6 个答案:

答案 0 :(得分:2)

您可以使用Uncaught ReferenceError: toastAlert is not definedreduce

  • 首先遍历items数组
  • 对于每个属性,我们将Set映射为最终对象上的键,并将值添加到相应的键中,因为我们只想保留唯一值,因此我们使用type
  • 现在我们的最终外观看起来像Set,但我们想要的格式是{type: { type, value }},因此我们使用{ type, size}Object.values()中获取{type, value},然后将其映射到所需格式

final

答案 1 :(得分:1)

您可以首先将结构简化为[类型,值]对。然后创建一个按类型作为键的地图,以集合作为值(以确保值的唯一性),填充该地图,最后将该地图转换为所需的结构:

var items = [{attributes: [{type: "Size",value: "Small"},{type: "Color",value: "Black"}]},{attributes: [{type: "Size",value: "Small"},{type: "Color",value: "White"}]},{attributes: [{type: "Size",value: "Medium"},{type: "Color",value: "Black"}]},{attributes: [{type: "Size",value: "Medium"},{type: "Color",value: "White"}]}];

const pairs = items.flatMap(({attributes}) => attributes.map(({type, value}) => [type, value]));
const map = new Map(pairs.map(([type]) => [type, new Set]));
pairs.forEach(([type, value]) => map.get(type).add(value));
const result = Array.from(map, ([type, values]) => ({ type, values: [...values] }));

console.log(result);

答案 2 :(得分:1)

var items = [
  {
    attributes: [
      {
        type: "Size",
        value: "Small"
      },
      {
        type: "Color",
        value: "Black"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Small"
      },
      {
        type: "Color",
        value: "White"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Medium"
      },
      {
        type: "Color",
        value: "Black"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Medium"
      },
      {
        type: "Color",
        value: "White"
      }
    ]
  }
];



var temp={};  // temporarly holder

items.forEach(function(item){  // iterate through each element
   item.attributes.forEach(function(attr){  // iterate through attributes of each element
   
    if (!temp[attr.type]) { temp[attr.type] = []; }  // if this is the first time we encounter
                                                       // this attribute, create a new placeholder
                                                       
    if(temp[attr.type].indexOf(attr.value)<0) {   // only add the attribute value if it was
                                                   // not added before
            temp[attr.type].push(attr.value);
    };
   });
});

var result = [];  // create the output result array

Object.keys(temp).forEach(function(key){  // iterate thought the keys of the temp object
  // add a new element with the properties congigured as desired
  result.push({type:key, values:temp[key]});
  
});

console.log(result);

答案 3 :(得分:1)

var items = [
  {
    attributes: [
      {
        type: "Size",
        value: "Small"
      },
      {
        type: "Color",
        value: "Black"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Small"
      },
      {
        type: "Color",
        value: "White"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Medium"
      },
      {
        type: "Color",
        value: "Black"
      }
    ]
  },
  {
    attributes: [
      {
        type: "Size",
        value: "Medium"
      },
      {
        type: "Color",
        value: "White"
      }
    ]
  }
];

var results=[];
var type=[];
var values=[];

for(var i=0; i<items.length;i++){
  var x=items[i].attributes;
  for(var j=0; j<x.length;j++){
    var pos=type.indexOf(x[j].type);
    if(pos==-1){
      type.push(x[j].type);
      values.push([]);
      pos=type.length-1;
    }
    if(values[pos].indexOf(x[j].value)==-1) values[pos].push(x[j].value);
  }
}

for(var i=0; i<type.length;i++){
  results.push({type:type[i],values:values[i]})
}

console.log(results);

答案 4 :(得分:1)

您不想使用map,您想使用reduce。

sql2 = 'SELECT A.DescripcionProducto,A.TipoUnidad,A.ExistenciaProducto,MAX(Concat(DATE_FORMAT(FechaSalida, "%d-%m-%Y")," ",time_format(FechaSalida,"%r"))) FROM newdb.inventario A LEFT JOIN newdb.inventariodetalle B ON A.IdProducto = B.IdProducto where DescripcionProducto = %s GROUP BY A.IdProducto'

答案 5 :(得分:0)

这将产生稍微不同的输出。一个对象而不是对象数组。

Traceback (most recent call last):
  File "/home/Sourabh58/bot1.py", line 25, in <module>
    browser.find_element_by_name("username").send_keys('be_fully_motivated')
  File "/usr/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 365, in find_element_by_name
    return self.find_element(by=By.NAME, value=name)
  File "/usr/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 752, in find_element
    'value': value})['value']
  File "/usr/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
    self.error_handler.check_response(response)
  File "/usr/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"name","selector":"username"}