将数组转换为键值对对象

4

我还在学习JavaScript,如果这个问题看起来很基础,请提前谅解。

我正在以数组的形式从API调用中接收数据,如下所示:

arr = ['topic1',497,'topic2',591,'topic3',17,'topic4',980]

尽管在该数组中不明显,但每个主题字符串后面的数字是前一个主题的计数。
我想在React应用程序中使用此数据,即将其映射到表格或其他数据结构。但当这些值像这样匿名时,这非常难以做到。
因此,我想将此数组转换为具有键/值对的对象。因此,在对数组进行某种循环/过滤/映射等操作后,我需要得到以下结果:
newArr = [
  {topic: 'topic1', count: 497},
  {topic: 'topic2', count: 591},
  {topic: 'topic3', count: 17},
  {topic: 'topic4', count: 980},
]

我尝试过很多技术,包括使用字典、地图、map、filter、forEach、for ... in 等等。是的,我搜索了很多网页和论坛。问题在于,我的问题涉及JavaScript的一些基本组成部分,所以我找到的答案从来都不够具体。

我成功地过滤出了数组中的偶数和奇数元素,就像这样:

let x = arr.filter((element, index) => {
  return index % 2 === 0; filter elements located at an even index
});

let y = arr.filter((element, index) => {
  return index % 2 === 1; filter elements located at an odd index
});

但是我从未成功地获得所需的结果。有人可以帮忙指导我吗?

我正在使用React,因此可以建议现代JS技术。谢谢!


1
因为您是新用户,这里有一个有用的建议:数组和对象在许多编程语言中都被广泛使用。因此,请为您的问题添加适当的语言标签(我已经替您在这个问题上添加了标签)。 - Reporter
如果两个数组相等,则循环它们并创建一个对象,然后添加到一个数组中! - Bharadwaj
1
谢谢,报告人...知道了! Bharadwaj,我想我明白了,但是只有一个由主题、计数、主题、计数等组成的单个数组。因此,每对项目之间存在关联。通过这种方式组合两个过滤后的数组,我可以确保生成的对象在正确的顺序中保持正确的关系吗? - patrickrs
明白了,那么你应该使用 forEach - Bharadwaj
1
GalAbra,如果这是一个重复的帖子,我就无法理解那篇帖子了。 :) 在这种情况下,我所拥有的是从API返回的数组结构永远不会改变...只有数据会改变。因此,我需要一些函数来获取数据,无论数组长度长短如何,将每个元素映射到“主题”或“计数”,视情况而定。我从不需要动态添加或删除属性。我发出调用,获取数组,执行转换。然后我就有了一个很好的对象,可以映射到表格或任何我想要的东西。 - patrickrs
3个回答

4
你需要遍历API响应并从数组构建对象。
let objectArray = []

for(let i = 0; i < arr.length - 1; i+=2){
    objectArray.push({"topic": arr[i], "count": arr[i+1]})
}

我相信有更简单的方法来完成它,但这将会得到你所需的结果。 在jsFiddle上查看实际效果:https://jsfiddle.net/L6023fn6/1/

非常感谢!这正是我想要做的。真是令人震惊,它实际上是如此简单!我还有很多要学习的... - patrickrs

1
你可以使用 array.reduce 来实现这个功能,它接受一个数组并返回一个聚合值、数组、对象或其他内容。完整的实现代码如下:
const newArr = arr.reduce((fonts, value, index) => {
   if (0 === index % 2) {
     fonts.push({ topic: value });
   } else {
     // output array will be half the size of the input hence the / 2
     fonts[Math.ceil(index / 2 - 1)].count = value;
   }

   return fonts;
}, []);

如果你愿意使用像lodash这样的外部库,那么这将变得更加容易,因为它会为你分块数组。
const newArr = _.zipWith(_.chunk(arr, 2), a => ({ topic: a[0], count: a[1] }));

上面的“for循环”解决方案实际上给了我所需的结果。不过还是谢谢你的帮助! - patrickrs

0
从你的问题来看,arr 是一个 字符串,数字... 的模式,根据这个模式,我觉得你可以这样做。
const arr = ['topic1',497,'topic2',591,'topic3',17,'topic4',980];
const result = [];

for(let i=0; i<arr.length; i+=1) {
 typeof arr[i] === 'string' 
 ?
  result.push({topic: arr[i], count: arr[i+1]})
:
null;

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接