如果满足条件,则求和并组合数组中相似的对象元素 - Javascript
我有一个这种形状的数组:
[
{
unique: 8,
views: 24,
name: "https://l.instagram.com/",
sec: 5.39,
},
{
unique: 2,
views: 20,
name: "",
sec: 0,
},
{
unique: 2,
views: 5,
name: "https://www.tiktok.com/",
sec: 5.39,
},
{
unique: 4,
views: 3,
name: "https://l.instagram.com",
sec: 2.00,
},
{
unique: 1,
views: 2,
name: "https://www.tiktok.com",
sec: 2.00,
},
];
我试图将相同的引用与值(视图、唯一等)的总和组合到一个新数组中。 新数组需要根据条件形成,基本上引用者名称需要根据类型进行格式化。例如,所有(“https://l.instagram.com/”、“l.instagram.com”、“https://www.instagram.com/”等)推荐人都需要被称为 Instagram,并且与其他人相同 - YouTube 、TikTok 等,如果为空,则为“Direct”。 这就是我想到的最终结果:
[
{
unique: 12,
views: 27,
name: "Instagram",
sec: 7.39,
},
{
unique: 2,
views: 20,
name: "Direct",
sec: 0,
},
{
unique: 3,
views: 7,
name: "TikTok",
sec: 7.39,
},
];
我的想法是映射数组,如果该值包含所需的字符串,它将对新对象中的值求和。也许是映射或减少,或者两者的组合? 任何指导或帮助表示赞赏。提前致谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,请在未来展示你自己的尝试。如果其他人还没有发布解决方案,我就不会发布解决方案,因为问题本身没有表现出足够的努力。
其中最大的挑战就是简单地将
"https://www.tiktok.com"
转换为"TikTok"
。我最初的解决方案使用正则表达式测试:/tiktok/i .test (name)
。这里有针对 Instagram 和 TikTok 的单独的内容,并且很明显如何添加其他内容。其他一切都相当简单。它看起来像这样:groupBy
(现在是一个阶段-3 提议对Array.prototype
进行扩展,因此可能不再需要太久)根据键生成函数的结果对数组的元素进行分组。也就是说,sumOn
接受一个属性名称列表并返回一个函数,该函数接受一个对象列表并返回一个新对象,其中每个属性名称都经过计算作为每个提供的对象的该属性的总和。groupName
是我们上面讨论的。它对 Instagram 和 TikTok 的正则表达式进行硬编码,并进行测试以查看这些字符串是否包含在名称中,如果不匹配则默认为“Direct”
。convert
是主要函数,它只不过是组合这些函数,使用groupName
作为groupBy
,获取条目,然后将组名称与调用sumOn
获取值的结果组合起来,键为['unique', 'views', 'sec ']
。这可能很好,但我正在考虑如何使其更可配置,虽然我不会详细介绍,但我确实有一个解决方案,可以让我们配置
"Instagram"
和直接“TikTok”
,以及列出我们想要总计的字段。它看起来像这样:First off, please in the future, show your own attempts. I wouldn't be posting a solution if others hadn't already, as there was not enough effort demonstrated in the question itself.
The biggest challenge in this is simply converting, say,
"https://www.tiktok.com"
to"TikTok"
. My initial solution uses a regex test:/tiktok/i .test (name)
. Separate ones for Instagram and TikTok are here, and it's obvious how to add additional ones. Everything else is fairly straightforward. It looks like this:groupBy
(now a stage-3 proposal for an extension toArray.prototype
, so may not be needed for much longer) groups the elements of an array according to a the result of a key-generating function. That is,sumOn
takes a list of property names and returns a function that takes a list of objects and returns a new object with each of those property names, calculated as the sum of that property for each of the supplied objects.groupName
is what we discussed above. It hard-codes regular expressions for Instagram and TikTok, with tests to see if those strings are included in the name, defaulting to"Direct"
if those don't match.convert
is the main function, which does little more than combine those function, usinggroupName
as the key-generating function forgroupBy
, taking the entries, then combining the group names with the result of callingsumOn
for the values, with keys of['unique', 'views', 'sec']
.This may be fine as is, but I was thinking about how to make this more configurable, and while I won't go through the details, I do have a solution that lets us configure
"Instagram"
and"TikTok"
directly, as well as list the fields that we want to total. It looks like this:(抱歉,我错过了此“直接”要求,会修改和附加)
array.map
和所有数组循环方法,一次通过数组一次迭代一个元素,而无需保留以前元素的信息,并且对未来元素视而不见,因此在循环循环您的对象时,需要一些方法来跟踪以前的对象。在我提出的摘要解决方案中,我声明了一个中间对象,其中包含您要一起收集的每个不同组的对象(在您的情况下,Tiktok和Instagram, - 如果您的初始数据集非常复杂,但在这个示例我只是用眼睛阅读它们)。
接下来,通过使用
for-east
循环来循环原始的对象数组。对于每个元素(对象),检查了.name
属性,并尝试提取可以用作中间数组中匹配对象的键的子字符串。这是通过将.name
分配到数组中来完成的,在发现周期(。)的任何地方都打破名称字符串。因为您的名字是所有类型(某物).tiktok。(某物),可以将唯一键(tiktok)提取为该拆分数组的seceond元素(index 1):this
key
现在可以用来在我们之前声明的对象的中间对象中引用相关对象,并且可以这样访问和更新单个属性:for-east
的语句如果块将循环放入有条件的中,以忽略任何未定义名称的地方。
for-each
循环完成后,数据现在将在对象的对象中(内在对象都按照您需要更新)。因此,最后,我们只需要将更新的对象移动到它们自己的数组中:
最终结果是一个包含每个命名组的对象的数组,其值来自每个对象组合的数组。
编辑不确定对象名称的“直接”组:
而不是有条件测试名称的
,我使用三元运算符来问“ dod dig split('。'。)返回有效的字符串 [1]中?
在
元素 直接为命名对象;
(sorry, I missed this 'direct' requirement, will modify and append)
Array.map
, and all array looping methods, iterate through the array an element at a time, without retaining information of previous elements, and blind to future elements so some means of keeping track of previous objects is needed while looping through your object.In my proposed snippet solution, I declare an intermediate object containing objects for each of the different groups you want to collect together (tiktok and instagram in your case, - you may beed to extract these programatically if your initial data set is very complex but in this example I simply read them by eye).
Next, the original array of objects is looped through using a
for-each
loop. for each element (object), the.name
property is examined and an attempt to extract a substring that can be used as a key to reference the matching object in the intermediate array. This was done by splitting the.name
into an array, breaking the name string wherever a period (.) was found. Because your names are all of the type (something).tiktok.(something), the unique key (tiktok) can be extracted as the seceond element (index 1) of that split array:This
key
can now be used to reference the relevant object in the intermediate object of objects we declared earlier, and individual properties can be accessed and updated like this:The statements of the
for-each
loop are put inside a conditionalif
block to ignore any where no name is defined.When the
for-each
loop is finished, the data will now be in an object of objects (with the inner objects all updated as you want them).So, finally we just need to move the updated objects into an array of their own:
The final result is an array containing one object for each named group, with the values from the original array of objects combined for each.
Edits to include 'direct' group for undefined object names:
Instead of the
if
conditional to test for a name, I instead used a ternary operator to ask "did split('.') return a valid string in element[1]? is so use it as name, if not use 'direct' as name"(the syntax looks odd but means what I quotted above:
Of course, the intermediate object of objects also had to be amended to include 'direct' as a named object;
您可以使用:
数组#降低
,object.entries
和object.fromentries
You can use a combination of:
Array#map
,Array#reduce
,Object.entries
, andObject.fromEntries
获取单独数组中的名称。迭代该数组并将其与主数组匹配。您还可以尝试通过用 (.) 分割来获取网站名称,并在
is
语句中将===
更改为includes
。像这样的事情:
Get the names in a separate array. Iterate that array and match it with the main array. You can also try getting the name of the website by splitting with (.) and in the
is
statement change===
toincludes
.Something like this: