我有两个数组
array1 =['0-18''18-19','18-19','18-19','20-22']
每个array1在第二个数组中都有值
array2=['100','200','300','400','500']
我想要输出
array1 =['0-18''18-19','20-22']
array2=['100','900','500']
请帮助填充这2个数组。 用Javascript
答案 0 :(得分:1)
您可以做的一件事是遍历array1
并将元素添加为对象中的键。对象键是唯一的,因此将消除重复项。这样做时,您可以从array2
添加相应的元素。
let array1 =['0-18','18-19','18-19','18-19','20-22']
let array2=['100','200','300','400','500']
let sums = array1.reduce((obj, key, index) => {
if (!obj.hasOwnProperty(key)) obj[key] = 0 // if we haven't added the key, do it and set it to zero
obj[key] += Number(array2[index]) // now add the amount from array2
return obj
}, {})
console.log(Object.keys(sums)) // the unique keys will be in the keys of the object
console.log(Object.values(sums)) // the sums will be in the values
答案 1 :(得分:0)
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]) => ...
还是不理想。
第三种格式是迄今为止最明确的格式。它直接链接每组中的两个数据,而不必依赖于您匹配索引。它还直接告诉您这两个部分代表什么。这可能不是最佳的存储格式,因为它占用更多空间,但使用起来最容易。
如果数据来自您无法控制的系统,则可能无法直接对其进行更改,但仍可以在代码内对其进行转换。这是一个将从Format 3
和array1
创建array2
的代码段:
const data = array1.map((range, idx) => ({range, value: array2[idx]}))
此格式仍然存在一件事。我们想对value
进行算术运算。但是现在它们被存储为字符串。我们确实应该将它们转换为数字。对该代码段稍作更改即可解决此问题:
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)