将类型引用为索引时出错

问题描述 投票:0回答:2

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

let sampleData = [
    { valueObj: { High: 4, Low: 5,  Medium: 7 } , time: "1571372233234" , sum: 16 },
    { valueObj: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},
    { time: "14354545454", sum: 0},
    { time: "14354545454", sum: 0} }
];

我需要获取数组内每个对象内的每个键,并从中形成一个数组。基本上基于所有对象中存在的键进行分组。如果对象没有“值”,则应在val1,val2,val3中返回0。

result = [
  { name: 'High', data: [4, 5, 0, 0] }, 
  { name: 'Medium', data: [5, 3, 0, 0] }, 
  { name: 'Low', data: [7, 1, 0, 0] }
];

这里我传递一个字符串,该字符串将在reduce中使用。我收到此错误任何不能用作索引每当我传递一个动态字符串时,只要启用了打字稿,该字符串都将在reduce函数中使用。

代码运行正常,但是在我升级到最新的TS之后,它抛出了错误并且无法编译

有人可以帮我吗?

我尝试了以下操作:

const sampleData = [{ valueObj: { High: 4, Low: 5,  Medium: 7 }, time: "1571372233234", sum: 16 }, { valueObj: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234", sum: 9 }, { time: "14354545454", sum: 0 }, { time: "14354545454", sum: 0 }];

const keys = ['High', 'Low', 'Medium'];

function formResult(sampleData, prop, keys){
  let grouped = sampleData.reduce((r, { [prop]: values = {} } = {}) => {
    r.forEach(({ name, data }) => data.push(values[name] || 0));       
    return r;
  }, keys.map(name => ({ name, data: [] })));
  console.log(grouped);
}

formResult(sampleData,"valueObj", keys);
javascript typescript ecmascript-6 ecmascript-5 ecmascript-7
2个回答
0
投票

该函数未返回grouped。可能是问题

const sampleData = [{
  valueObj: {
    High: 4,
    Low: 5,
    Medium: 7
  },
  time: "1571372233234",
  sum: 16
}, {
  valueObj: {
    High: 5,
    Low: 3,
    Medium: 1
  },
  time: "1571372233234",
  sum: 9
}, {
  time: "14354545454",
  sum: 0
}, {
  time: "14354545454",
  sum: 0
}];

const keys = ['High', 'Low', 'Medium'];

function formResult(sampleData, prop, keys) {
  return sampleData.reduce((r, {
    [prop]: values = {}
  } = {}) => {
    r.forEach(({
      name,
      data
    }) => data.push(values[name] || 0));
    return r;
  }, keys.map(name => ({
    name,
    data: []
  })));

}

console.log(formResult(sampleData, "valueObj", keys));

0
投票

使用带有Typescript的动态键的reduce可能很丑陋,并且在创建单个对象时为arguably not appropriate even in Javascript。考虑创建将数据放入循环之外的对象-一种对象,其属性是名称(高等),值是数字数组。在每次迭代时推送到number数组(如果该属性不存在,则推0),如果需要,首先使用该数组创建该属性。循环后,将对象变成对象数组:

// compliant with noImplicitAny and strict options
type DataItem = {
    time: string;
    sum: number;
    valueObj?: {
        High: number;
        Medium: number;
        Low: number;
    }
};
const sampleData: DataItem[] = [
    { valueObj: { High: 4, Low: 5,  Medium: 7 } , time: "1571372233234" , sum: 16 },
    { valueObj: { High: 5, Low: 3, Medium : 1 }, time: "1571372233234" , sum: 9},
    { time: "14354545454", sum: 0},
    { time: "14354545454", sum: 0}
];
const keys = ['High', 'Low', 'Medium'] as const;
const grouped = {} as { [key: string]: number[] };
for (const item of sampleData) {
    for (const key of keys) {
        if (!grouped[key]) {
            grouped[key] = [];
        }
        grouped[key].push(item.valueObj ? item.valueObj[key] : 0);
    }
}
const output = Object.entries(grouped).map(([name, data]) => ({ name, data }));

编译输出:

"use strict";
const sampleData = [
    { valueObj: { High: 4, Low: 5, Medium: 7 }, time: "1571372233234", sum: 16 },
    { valueObj: { High: 5, Low: 3, Medium: 1 }, time: "1571372233234", sum: 9 },
    { time: "14354545454", sum: 0 },
    { time: "14354545454", sum: 0 }
];
const keys = ['High', 'Low', 'Medium'];
const grouped = {};
for (const item of sampleData) {
    for (const key of keys) {
        if (!grouped[key]) {
            grouped[key] = [];
        }
        grouped[key].push(item.valueObj ? item.valueObj[key] : 0);
    }
}
const output = Object.entries(grouped).map(([name, data]) => ({ name, data }));
console.log(output);
© www.soinside.com 2019 - 2024. All rights reserved.