如何从阵列数组创建“扁平”组?

时间:2021-11-05 12:03:23

I have a crossfilter built from a list of posts made by a user, and I want to use the data to drive a word cloud-style visualisation.

我有一个由用户发布的帖子列表构建的交叉过滤器,我想使用这些数据来驱动单词云样式的可视化。

My records are an array of objects like this:

我的记录是这样的对象数组:

[
    {
      "date": Thu May 24 2018 11:29:27 GMT+0100 (GMT Daylight Time),
      "text": "Lorem ipsum dolor sit amet"
    },
    ...etc
]

I've set up some dimensions on the date field to filter my records, and I'd like the contents of the word cloud to update to reflect the filtered data. I'm not sure how to set up a group that is a flat array of every word in the filtered post.

我在日期字段上设置了一些维度来过滤我的记录,我希望更新单词云的内容以反映过滤后的数据。我不确定如何设置一个组,该组是过滤后的帖子中每个单词的平面数组。

Setting up a dimension like this

设置这样的维度

var textDimension = ndx.dimension(p => p.split(' '))

will give

[
    ['Lorem', 'ipsum', 'dolor',  'sit', 'amet'],
    ...etc
]

which is fine but there doesn't seem to be a way to do textDimension.group(/* do something...*/).reduceSum(r => 1) that treats the dimension as

这很好,但似乎没有办法做textDimension.group(/ *做某事...... * /)。reduceSum(r => 1)将维度视为

[
    'Lorem',
    'ipsum',
    'dolor',
    'sit',
    'amet'
]

which after the reduceSum would produce something like

在reduceSum之后会产生类似的东西

[
    {"key": "Lorem", "value": 1},
    {"key": "ipsum", "value": 1},
    {"key": "dolor", "value": 1},
    {"key": "sit", "value": 1},
    {"key": "amet", "value": 1},
]

instead of

[
    {"key": ['Lorem', 'ipsum', 'dolor',  'sit', 'amet'], "value": 1},
]

which is how it currently does with do logic in group(). I could do what I want with

这就是它目前如何处理group()中的逻辑。我可以做我想做的事

var filteredPosts = ndx.allFiltered()
var wordsByPost = filteredPosts.map(p => p.split(' ')
var allWords = [].concat.apply([], wordsByPost)

and then count up the instances of each word in allWords (potentially by setting up a new crossfilter) but it feels like the wrong way to do it.

然后计算allWords中每个单词的实例(可能通过设置一个新的crossfilter),但感觉这是错误的方法。

Is there a way to do this using the crossfilter I've already got set up or do I admit defeat and use the basic JS solution?

有没有办法使用我已经设置的crossfilter来做到这一点,或者我承认失败并使用基本的JS解决方案?

2 个解决方案

#1


1  

If you are using Crossfilter 1.4+, then you just need to tell it that the dimension is an array dimension like so:

如果您使用的是Crossfilter 1.4+,那么您只需告诉它维度是一个数组维度,如下所示:

var textDimension = ndx.dimension(p => p.split(' '), true)

Documentation: https://github.com/crossfilter/crossfilter/wiki/API-Reference#dimension_with_arrays

#2


2  

Once you have all the words in an array, you can flatten your array, then using array#reduce you can group the array based on the unique words in an object accumulator. Then get all values from the object using Object.values().

一旦你有一个数组中的所有单词,你可以展平你的数组,然后使用数组#reduce你可以根据对象累加器中的唯一单词对数组进行分组。然后使用Object.values()从对象获取所有值。

const data = [ { "date": 'Thu May 24 2018 11:29:27 GMT+0100 (GMT Daylight Time)', "text": "Lorem ipsum dolor sit amet" }, { "date": 'Thu May 24 2018 11:29:27 GMT+0100 (GMT Daylight Time)', "text": "Lorem ipsum2 dolor2 sit amet" } ],
    result = Object.values([].concat(...data.map(({text}) => text.split(' ')))
               .reduce((r,w) => {
                 r[w] = r[w] || {key: w, value : 0};
                 r[w].value += 1;
                 return r;
               },{}));
console.log(result);

#1


1  

If you are using Crossfilter 1.4+, then you just need to tell it that the dimension is an array dimension like so:

如果您使用的是Crossfilter 1.4+,那么您只需告诉它维度是一个数组维度,如下所示:

var textDimension = ndx.dimension(p => p.split(' '), true)

Documentation: https://github.com/crossfilter/crossfilter/wiki/API-Reference#dimension_with_arrays

#2


2  

Once you have all the words in an array, you can flatten your array, then using array#reduce you can group the array based on the unique words in an object accumulator. Then get all values from the object using Object.values().

一旦你有一个数组中的所有单词,你可以展平你的数组,然后使用数组#reduce你可以根据对象累加器中的唯一单词对数组进行分组。然后使用Object.values()从对象获取所有值。

const data = [ { "date": 'Thu May 24 2018 11:29:27 GMT+0100 (GMT Daylight Time)', "text": "Lorem ipsum dolor sit amet" }, { "date": 'Thu May 24 2018 11:29:27 GMT+0100 (GMT Daylight Time)', "text": "Lorem ipsum2 dolor2 sit amet" } ],
    result = Object.values([].concat(...data.map(({text}) => text.split(' ')))
               .reduce((r,w) => {
                 r[w] = r[w] || {key: w, value : 0};
                 r[w].value += 1;
                 return r;
               },{}));
console.log(result);