使用 reduce() 将元素拆分为数组

Split element into array with reduce()

我在图表中有一些边,我得到的是:

const edges = getEdges();

每条边都有一个标签数组,我得到的是:

const edges = getEdges().map(function (edge, i) {
  return (i + 1) + '-' + getLabels(edge).sort().join('-');
});

所以如果我有 2 条边,每条边都有两个标签,我得到一个数组

[
  '1-label1-label2',
  '2-label1-label2'
]

但我想要的是

[
  '1-label1',
  '2-label2',
  '3-label1',
  '4-label2'
]

所以我想我需要使用 Array.reduce()

使用Array#reduce方法做这样的事情。

const edges = getEdges().reduce(function(arr, edge) {
  return arr.concat(
    getLabels(edge)
    .sort()
    .map(function(v, i) {
      return (arr.length + i) + '-' + v;
    })
  );
}, []);

使用Array#push method instead of Array#concat方法。

const edges = getEdges().reduce(function(arr, edge) {
  [].push.apply(arr, getLabels(edge)
    .sort()
    .map(function(v, i) {
      return (arr.length + i) + '-' + v;
    })
  );
  return arr;
}, []);

在我看来,mapreduce 都不是您真正想要的,只是嵌套的一对 forEach(尽管我们可以用鞋拔 reduce 如果我们想要的话):

const edges = [];
getEdges().forEach(edge => {
  getLabels(edge).sort().forEach(label => {
    edges.push(`${(edges.length + 1)}-${label}`);
  });
});

实例:

const getEdges = () =>
  [
    {labels: ['label2', 'label1']},
    {labels: ['label1', 'label2']}
  ];
const getLabels = edge => edge.labels;

const edges = [];
getEdges().forEach(edge => {
  getLabels(edge).sort().forEach(label => {
    edges.push(`${(edges.length + 1)}-${label}`);
  });
});
console.log(edges);

您可以对边使用缩减操作,它获取每条边并添加到新构造的数组中。

在每条边的标签上使用 forEach 会产生 1..n 个项目,这些项目将被添加到这个新数组中。使用新数组(result)的当前长度可以巧妙的解决result项随意命名的问题(即从1到N)。

const res = getEdges().reduce(result, edge => {
  const labels = getLabels(edge).sort();
  labels.forEach(label => result.push(`${result.length + 1}-${label}`));
  return result;
}, []);

注意:此解决方案使用 reduce 和 ES6 功能,根据提到的标签。

您可以先将 getEdges 的结果映射到 getLabels,然后使用 Array.prototype.concat 和展开语法展平结果数组。

const getEdges = () => ['a', 'b'];
const getLabels = () => ['label1', 'label2'];

const edges = [].concat(...getEdges().map(getLabels))
  .map((label, i) => `${i + 1}-label`);
console.log(edges);

您可以使用 forEach 代替 mapreduce

工作代码段:(ES6)

const getEdges = () => [
     '1-label1-label2',
     '2-label1-label2'
   ];

const getLabels = (edge) => edge.split('-').sort();

let edges = [];

getEdges().forEach((edge) => {
  getLabels(edge).forEach((label) => {
    if(label.indexOf('label') > -1) {
       edges.push(edges.length + 1 + '-' + label);
    }
  });
});

console.log(edges);

工作代码段:(ES5)

function getEdges() {
   return [
     '1-label1-label2',
     '2-label1-label2'
   ];
}

function getLabels(edge) {
  return edge.split('-').sort();
}

var edges = [];

getEdges().forEach(function (edge) {
  getLabels(edge).forEach(function (label) {
    if(label.indexOf('label') > -1) {
       edges.push(edges.length + 1 + '-' + label);
    }
  });
});

console.log(edges);