将对象数组简化为单个对象,并为每个单个对象调用一个函数

时间:2019-05-13 14:51:10

标签: javascript arrays object iterator reduce

我有一组对象。 我需要将其转换为对象的对象。在尝试执行此操作时,我需要为每个对象调用另一个函数。

您能帮我吗?

代码:

function convertData() {
 var arr = {"items": [ {"type": "color"}, {"type": "number" }]};
 arr.items.reduce(function(item, index) {
   return {
    /*for each obj in items call formatItems before assigning it here */
    item: formatItems(item)
   }
 });

  console.log(arr);
}

function formatItems(item, index) {
  return {
    type: "string",
    id: "item-"+index
  }
}
<button onclick="convertData()">Click me!</button>

预期输出:

{
  "0": {
    "type": "string",
    "id": "item-1"
  },
  "1": {
    "type": "string",
    "id": "item-2"
  }
}

3 个答案:

答案 0 :(得分:3)

使用具有属性名称(例如"0""1")的对象确实令人怀疑。我只是继续使用一个数组,您可以通过map轻松创建它(但请继续阅读非数组对象选项):

var result = arr.items.map(formatItems);

实时示例:

function convertData() {
  var arr = {"items": [ {"type": "color"}, {"type": "number" }]};
  var result = arr.items.map(formatItems);
  console.log(result);
}

function formatItems(item, index) {
  return {
    type: "string",
    id: "item-"+index
  };
}

convertData();


但是如果您真的想要一个非数组对象,那么如果您真的想使用reduce,那么代码就非常接近了。查看评论:

var result = arr.items.reduce(function(obj, item, index) {
  //                                   ^^^-- receive the "accumulator" as the first param
  obj[index] = formatItems(item); // Create the property on the object
  return obj;                     // Return the same object
}, {});                           // Start with a blank object

实时示例:

function convertData() {
  var arr = {"items": [ {"type": "color"}, {"type": "number" }]};
  var result = arr.items.reduce(function(obj, item, index) {
    //                                   ^^^-- receive the "accumulator" as the first param
    obj[index] = formatItems(item); // Create the property on the object
    return obj;                     // Return the same object
  }, {});                           // Start with a blank object
  console.log(result);
}

function formatItems(item, index) {
  return {
    type: "string",
    id: "item-"+index
  };
}

convertData();


但是,当您刚从接收的回调中传递相同的对象时,reduce并不是最好的工具。您只需要一个简单的循环:

var result = {};
for (const [index, item] of arr.items.entries()) {
  result[index] = formatItems(item);
}

实时示例:

function convertData() {
  var arr = {"items": [ {"type": "color"}, {"type": "number" }]};
  var result = {};
  for (const [index, item] of arr.items.entries()) {
    result[index] = formatItems(item);
  }
  console.log(result);
}

function formatItems(item, index) {
  return {
    type: "string",
    id: "item-"+index
  };
}

convertData();

Adiga has a much simpler ES2015+ option


或者如果您需要ES2015之前的版本:

var result = {};
for (int index = 0; index < arr.items.length; ++index) {
  result[index] = formatItems(arr.items[index]);
}

实时示例:

function convertData() {
  var arr = {"items": [ {"type": "color"}, {"type": "number" }]};
  var result = {};
  for (var index = 0; index < arr.items.length; ++index) {
    result[index] = formatItems(arr.items[index]);
  }
  console.log(result);
}

function formatItems(item, index) {
  return {
    type: "string",
    id: "item-"+index
  };
}

convertData();

答案 1 :(得分:2)

在ES6中,您可以map arr.itemsspread{}内的结果数组。这将创建一个以数组索引为属性的对象

function formatItems(item, index) {
  return { type: "string", id: "item-"+index }
}

const arr = { "items": [ {"type": "color"}, {"type": "number" }] };

const output = { ...arr.items.map(formatItems) } 
      
console.log(output)

答案 2 :(得分:0)

您需要将initialValue作为空object传递给减速器。

示例:

function convertData() {
 var arr = {"items": [ {"type": "color"}, {"type": "number" }]};
 const res = arr.items.reduce(function(acc, item, index) {
    const out = formatItems(item, index)

    //change this if you need an indexed keys, like acc[index] = out
    acc[out.id] = out
    return acc
 }, {});

   console.log(res);
}

function formatItems(item, index) {
  return {
    type: "string",
    id: "item-"+index
  }
}
convertData()