Javascript JS按具有两个不同数组和总和值的组分组数组值

Javascript JS按具有两个不同数组和总和值的组分组数组值,javascript,Javascript,我有两个数组 array1 =['0-18''18-19','18-19','18-19','20-22'] 每个数组1在第二个数组中都有值 array2=['100','200','300','400','500'] 我想要像这样的输出 array1 =['0-18''18-19','20-22'] array2=['100','900','500'] 请帮助填写这2个阵列。 在Javascript中,可以做的一件事是循环遍历array1,并将元素作为键添加到对象中。对象键是唯一的,因此

我有两个数组

array1 =['0-18''18-19','18-19','18-19','20-22']
每个数组1在第二个数组中都有值

array2=['100','200','300','400','500']
我想要像这样的输出

array1 =['0-18''18-19','20-22']
array2=['100','900','500']
请帮助填写这2个阵列。
在Javascript中,可以做的一件事是循环遍历
array1
,并将元素作为键添加到对象中。对象键是唯一的,因此这将消除重复项。执行此操作时,可以从
array2
添加相应的元素

let array1=['0-18','18-19','18-19','18-19','20-22']
设array2=['100','200','300','400','500']
让sums=array1.reduce((对象、键、索引)=>{
如果(!obj.hasOwnProperty(key))obj[key]=0//如果尚未添加该键,请执行该操作并将其设置为零
obj[key]+=Number(array2[index])//现在从array2添加金额
返回obj
}, {})
console.log(Object.keys(sums))//唯一键将位于对象的键中

console.log(Object.values(sums))//总和将在值中
Mark Meyer的回答非常好

不过,我想指出一些关于您的要求的其他方面

您的初始数据结构看起来不太理想。它使用两个单独的数组来保存仅由共享索引链接的相关数据段。我将在下面建议几个备选方案,但首先,我想指出,建议这可能是必需的,因为外部系统将此结构作为输出提供给您,或者将其作为输入提供给您,这是没有帮助的。外部系统可能会规定它们的输入和输出,但您始终可以将其转换为在两者之间对您有效的任何东西

更好的格式 共享索引数据格式之所以有问题,有几个原因:它很容易失去同步,不太明确,而且几乎从来没有真正描述过潜在的问题域

对于您的数据来说,以下任何一项都可能是更好的结构:

// Format 1
[
  {"0-18":  "100"},
  {"18-19": "200"},
  {"18-19": "300"},
  {"18-19": "400"},
  {"20-22": "500"}
]

// Format 2
[
  ["0-18",  "100"],
  ["18-19", "200"],
  ["18-19", "300"],
  ["18-19", "400"],
  ["20-22", "500"]
]

// Format 3
[
  {range: "0-18",  value: "100"},
  {range: "18-19", value: "200"},
  {range: "18-19", value: "300"},
  {range: "18-19", value: "400"},
  {range: "20-22", value: "500"}
]
第一种格式仍然很弱。它确实消除了共享索引问题。但这并不是那么容易处理的。第二个更容易使用。但是使用它的代码需要提供数据中缺少的一些信息,即范围是每个对的第一个成员,值是第二个,通过类似于
pair[0]
pair[1]
的方式,或者使用将数组分解为命名值的函数:
const foo=([range,value])=>…
这同样不理想

第三种格式是迄今为止最明确的。它直接链接每个集合中的两个数据段,而不依赖于您来匹配索引。它还直接告诉你这两个部分代表什么。这可能不是存储的最佳格式,因为它占用更多的空间,但最容易使用

转换为此格式 如果数据来自您无法控制的系统,您可能无法直接对其进行更改,但仍然可以在代码中对其进行转换。下面是一个片段,它将从
array1
array2
创建
Format 3

const data = array1.map((range, idx) => ({range, value: array2[idx]}))
更正内部数据类型 这种格式仍然有一个错误。我们想对
值进行算术运算。但现在它们存储为字符串。我们真的应该把它们转换成数字。对该代码段稍作更改即可解决此问题:

const data = array1.map((range, idx) => ({range, value: Number(array2[idx])}))
这将给我们

// Format 4
[
  {range: "0-18",  value: 100},
  {range: "18-19", value: 200},
  {range: "18-19", value: 300},
  {range: "18-19", value: 400},
  {range: "20-22", value: 500}
]
转换此数据 我们现在可以编写一些类似于Mark的代码,但更简单,因为我们从更明确的数据结构开始:

const sums = data.reduce((res, {range, value}) => {
  res[range] = (res[range] || 0) + value
  return res
}, {})
或者,如果我们要在多个地方使用它,我们可以编写一个可重用函数:

const transform = (data) => data.reduce((res, {range, value}) => {
  res[range] = (res[range] || 0) + value;
  return res
}, {})
// ... later ...
const sums = transform(data)
转换回单独的阵列 如果您确实需要两个单独的数组中的结果,这与Mark的答案一样:

const newArray1 = Object.keys(sums)
const newArray2 = Object.values(sums)
(或者,如果需要将总值转换回字符串,可以执行以下操作:

const newArray2 = Object.values(sums).map(String)

你能解释一下为什么每个数组都有最终值吗?对不起,我想你误解了。我不是问你为什么需要这样做,而是问为什么结果是这样的。为什么数组2会是
['100'、'900'、'500']
对不起。实际上数组1在数组2中有相应的值。当我们对数组1进行分组时,我们还必须根据分组对数组2的值求和。应该有一个“编辑”问题下的链接。在StackOverflow上,使用注释提示的信息编辑您的问题被认为是一种很好的形式,这样问题本身就包含了足够的信息来回答问题。关于第二个数组中的值求和的内容在这里很有价值。使用代码时,在console.log上获取错误(对象.价值(总和))-TypeError:Object.values不是函数
Object
应该有大写的“o”。如果这不是问题,包括错误。是的,我使用了o大写,但仍然得到错误----TypeError:Object.values不是function@t_azmathulla你在使用Internet Explorer吗?Mark-我在使用Chrome的同时使用代码获取console.log(object.values(sums))上的错误-TypeError:object.values不是一个函数-t_azmathulla 10秒前如果
object.values
不可用(通常情况下),很容易填充或编写自己的函数,比如
vals=(obj)=>object.keys(obj).map(k=>obj[k])
…然后
vals(sums)