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)
。