【问题标题】:How to construct an array of object to unique array of object如何将对象数组构造为唯一的对象数组
【发布时间】:2022-11-17 15:53:08
【问题描述】:

我有一个这样的对象数组

let data = 
[
    {
        text: 'label'
    },
    {
        text: 'username'
    },
    {
        text: 'category'
    },
    {
        text: 'book'
    },
    {
        text: 'john'
    },
    {
        text: 'education'
    },
    {
        text: 'car'
    },
    {
        text: 'doe'
    },
    {
        text: 'automotive'
    },
    {
        text: 'shoes'
    },
    {
        text: 'cena'
    },
    {
        text: 'fashion'
    },
]

和我期望的对象数组

let result = 
[
    {
        label: 'book',
        username: 'john',
        category: 'education'
    },
    {
        label: 'car',
        username: 'doe',
        category: 'automotive'
    },
    {
        label: 'shoes',
        username: 'cena',
        category: 'fashion'
    },
]

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 我试过取模,但我仍然堆叠结果

标签: javascript node.js arrays typescript object


【解决方案1】:

根据你的数据,前3条记录是属性名,其他是数据,所以我们可以使用Array.slice()来获取属性名

然后我们可以使用Array.reduce()转换左边的数据

let keys = data.slice(0,3).map(v => v.text)
let result = data.slice(3).reduce((a,c,i) =>{
  let key = keys[i%3]
  if(i%keys.length ==0){
   let obj = {}
   obj[key] = c.text
   a.push(obj)
  }else{
   a.at(-1)[key]=c.text
  }
  return a
},[])

console.log(result)

let data = 
[
    {
        text: 'label'
    },
    {
        text: 'username'
    },
    {
        text: 'category'
    },
    {
        text: 'book'
    },
    {
        text: 'john'
    },
    {
        text: 'education'
    },
    {
        text: 'car'
    },
    {
        text: 'doe'
    },
    {
        text: 'automotive'
    },
    {
        text: 'shoes'
    },
    {
        text: 'cena'
    },
    {
        text: 'fashion'
    },
]

let keys = Object.values(data.slice(0,3)).map(v => v.text)
let result = data.slice(3).reduce((a,c,i) =>{
  let key = keys[i%3]
  if(i%keys.length ==0){
   let obj = {}
   obj[key] = c.text
   a.push(obj)
  }else{
   a.at(-1)[key]=c.text
  }
  return a
},[])

console.log(result)

【讨论】:

  • Object.values(data.slice(0,3))等同于data.slice(0,3)
  • @pilchard 是的,Object.values()在这里是多余的,谢谢!
【解决方案2】:

switch-case 和模 % 运算符如何检查当前密钥:

const transformData = (data) => {
  let result = [];
  let tmpObj = {};
  data.forEach((element, idx) => {
    switch (idx % 3) {
      case 0:
        tmpObj["label"] = element.text;
        break;
      case 1:
        tmpObj["username"] = element.text;
        break;
      case 2:
        result.push({ ...tmpObj,
          category: element.text
        });
        tmpObj = {};
        break;
      default:
        break;
    }
  });
  return result;
};

console.log(transformData(getSampleData()));

function getSampleData() {
  return [{
      text: 'label'
    },
    {
      text: 'username'
    },
    {
      text: 'category'
    },
    {
      text: 'book'
    },
    {
      text: 'john'
    },
    {
      text: 'education'
    },
    {
      text: 'car'
    },
    {
      text: 'doe'
    },
    {
      text: 'automotive'
    },
    {
      text: 'shoes'
    },
    {
      text: 'cena'
    },
    {
      text: 'fashion'
    },
  ];
}

【讨论】:

  • 我看到我只需要更多循环条件,非常感谢
  • 如果这个答案对您有所帮助,我将不胜感激
【解决方案3】:

只是一个简单的for 循环可能是最清晰的。这里将每个对象存储在一个temp变量中,以避免每次迭代都必须访问结果数组的末尾,并将size抽象为一个变量。

let data = [{ text: 'label' }, { text: 'username' }, { text: 'category' }, { text: 'book' }, { text: 'john' }, { text: 'education' }, { text: 'car' }, { text: 'doe' }, { text: 'automotive' }, { text: 'shoes' }, { text: 'cena' }, { text: 'fashion' },];

const size = 3;
const result = [];
let temp;

for (let i = size; i < data.length; i++) {
  if (i % size === 0) {
    result.push(temp = {});
  }
  temp[data[i % size].text] = data[i].text;
}

console.log(result)

【讨论】:

    猜你喜欢
    • 2018-08-10
    • 2023-02-04
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多