2

I have some edges in a graph, which I get with:

const edges = getEdges();

Each edge has an array of labels, which I get with:

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

So if I have 2 edges, each with two labels, I get an array

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

But what I want is

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

So I guess I need to use Array.reduce().

1
  • 1
    What is the logic? Can we have an example of edges? Commented Dec 20, 2016 at 13:24

5 Answers 5

2

Using Array#reduce method do something like this.

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

Using Array#push method instead of Array#concat method.

const edges = getEdges().reduce(function(arr, edge) {
  [].push.apply(arr, getLabels(edge)
    .sort()
    .map(function(v, i) {
      return (arr.length + i) + '-' + v;
    })
  );
  return arr;
}, []);
Sign up to request clarification or add additional context in comments.

Comments

0

It doesn't seem to me that either map or reduce is what you actually want, just a nested pair of forEach (although we could shoe-horn a reduce in if we wanted):

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

Live Example:

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);

Comments

0

You can first map the result of getEdges to getLabels, and then flatten the resulting array with Array.prototype.concat and the spread syntax.

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

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

Comments

0

You can use forEach as below instead of map or reduce.

Working snippet: (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);

Working snippet: (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);

Comments

0

You could use a reduce operation on the edges, which takes each edge and adds to a newly constructed array.

Using a forEach on the labels of each edge results in 1..n items, that will be added to this new array. Using the new array (result)'s current length can neatly solve the problem of naming the result item as desired (i.e. from 1 to N).

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

NOTE: this solution uses reduce and ES6 features, which is according to mentioned tags.

2 Comments

While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!
added explanation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.