繁体   English   中英

按状态转换数据数组

[英]Transform an array of data by status

我需要按属性过滤数组:

这是我从服务器获取的数据:

const mockResults = [
  {
    user: {
      firstName: '1',
      lastName: '1'
    },
    status: 'WRONG'
  },
  {
    user: {
      firstName: '2',
      lastName: '2'
    },
    status: 'WRONG'
  },
  {
    user: {
      firstName: '3',
      lastName: '3'
    },
    status: 'CORRECT'
  }
];

要显示数据,我需要将其转换为 ReactNative SectionList 格式所需的格式:

const requiredFormat = [
  {
    status: 'WRONG',
    data: [{ user: {firstName: '1', lastName: '1'}}, { user: {firstName: '2', lastName: '2'}}],
  },
  {
    status: 'CORRECT',
    data: [{ user: {firstName: '3', lastName: '3'}}],
  },
];

基本上, mockResults应该按status排序。 最多可以有 4 种状态: correct, wrong, missed, chosen 所有这些状态都应该包括用它们标记的所有数据。

实现这一点的正确方法是什么?

我试图过滤数组,但我在这一点上卡住了:

const transformArray = mockResults.filter(item => {
  return {
    answerStatus: item.status,
    data: [item.user]
  }
})

您可以遍历数组(使用Array.prototype.reduce()方法)并在看到当前status没有这样的元素时创建结果数组的新元素,或者如果存在则附加当前元素数据:

 const mockResults = [{user:{firstName:'1',lastName:'1'},status:'WRONG'},{user:{firstName:'2',lastName:'2'},status:'WRONG'},{user:{firstName:'3',lastName:'3'},status:'CORRECT'}], result = mockResults.reduce((r,{status, ...rest}) => { const common = r.find(e => e.status == status) common ? common.data.push(rest) : r.push({status, data:[rest]}) return r }, []) console.log(result)
 .as-console-wrapper {min-height:100%}

您可以使用reduce()来实现:

 const mockResults = [{user: { firstName: '1', lastName: '1'}, status: 'WRONG'},{user: {firstName: '2',lastName: '2'},status: 'WRONG'},{user: { firstName: '3',lastName: '3'},status: 'CORRECT'}]; const result = mockResults.reduce((a, {user, status}) => { const temp = a.find(e => e.status === status); if (temp) { temp.data.push({user}); } else { a.push({status, data: [{user}]}); } return a; }, []); console.log(result);

Array.prototype.reduce()文档中阅读:

reduce()方法在数组的每个元素上执行一个 reducer 函数(您提供的),从而产生单个输出值。

我希望这有帮助!

您可以将数组缩减为一个对象,其键是状态属性,其值是具有该状态的用户数组。 然后,映射条目以将其转换回对象数组。

注意: reduce 函数在每个索引处创建一个新对象(累加器)。 这对于大型数据集可能不切实际,因为它真的很慢。

const toSectionList = results =>
  Object.entries(
    results.reduce(
      (obj, { user, status }) => ({
        ...obj,
        [status]: [...(obj[status] || []), { user }],
      }),
      {}
    )
  ).map(([status, data]) => ({ status, data }))

// example use:

const requiredFormat = toSectionList(mockResults)

这个函数中的 reduce 函数修改了累加器对象,而不是创建一个新对象。 对于更大的数据集,它应该表现得更好。

const toSectionList = results =>
  Object.entries(
    results.reduce((obj, { user, status }) => {
      obj[status] = obj[status] || []
      obj[status].push({ user })
      return obj
    }, {})
  ).map(([status, data]) => ({ status, data }))

这就是我所做的。

const mockResults = [
  {
    user: {
      firstName: '1',
      lastName: '1'
    },
    status: 'WRONG'
  },
  {
    user: {
      firstName: '2',
      lastName: '2'
    },
    status: 'WRONG'
  },
  {
    user: {
      firstName: '3',
      lastName: '3'
    },
    status: 'CORRECT'
  }
]

function format(data) {
  const resultDict = {}
  for (let i of data) {
    if (!resultDict[i.status]) {
      resultDict[i.status] = { data: [] }
    }
    resultDict[i.status].data.push(i)
    delete resultDict[i.status].data[resultDict[i.status].data.length - 1].status
  }

  const result = []
  for (let i in resultDict) {
    const res = {
      status: i,
      data: resultDict[i].data
    }
    result.push(res)
  }

  return result
}

console.log(format(mockResults))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM