0

I have an SVG image and I want to get all the colour hex codes in an array.

<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 <g display="inline">
  <title>Layer 1</title>
  <ellipse ry="116" rx="66" id="svg_1" cy="130.7" cx="375.2" stroke-width="3" stroke="#000000" fill="#FF0000"/>
  <ellipse ry="104" rx="68" id="svg_2" cy="133.7" cx="248.2" stroke-width="3" stroke="#000000" fill="#FF0000"/>
  <ellipse ry="73" rx="47" id="svg_3" cy="161.7" cx="231.2" stroke-width="3" stroke="#000000" fill="#FF0000"/>
  <rect id="svg_4" height="77" width="83" y="66.7" x="225.2" stroke-width="3" stroke="#000000" fill="#0000ff"/>
 </g>
</svg>

So in this case I have 3 different colours. Yet in total I have 8 as there are recurrences.

I can count all with.

 function count_colours(data){

    return data.match(/#/g).length;

}

And obviously I get eight plus any other occurrence of #.

The issue I have is anything I can think of is too heavy. I need a light simple solution if there is one. Is there a simple way to achieve this? Getting all the hex codes in an array with no duplicates would be amazing.

EDIT: OK, so iterate through the array and check the hex code is valid using..

 var isOk  = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test('#XXXXX') 

Then remove duplicates using

_.uniq(hex_codes);

But how would I build the initial array, that's the part I am struggling with. Would I use indexOf() in the initial iteration. This all seems very messy.

Iglo
  • 706
  • 2
  • 8
  • 17

2 Answers2

1

How about this?

function count_colours(data) {

   var n = 0, matches, cols = {};
   if (matches = data.match(/\#[0-9A-Fa-f]{3}([0-9A-Fa-f]{3})?/g)) {
      for (var i=0; i<matches.length; i++) {
          if (!cols[matches[i]]) {
             cols[matches[i]] = 1
             n++;
          }
      }
   }
   return n;
}

Demo here

You may also need to take account of the fact that "#00F", "#00f" and "#0000FF" are all the same colour but will be counted separately. I have assumed here that these files are produced by an editor or something similar which will be consistent in how it lists colours.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • This is perfect! And yes, the codes are produced consistently by an editor. Thank you. – Iglo Apr 27 '14 at 01:21
0

Yes there is, depends on your constraints.

I'd go for underscore utility function uniq, as it's not worth writing your own implementation.

http://underscorejs.org/#uniq

There is also another answer in relation to your question here: Removing duplicate objects with Underscore for Javascript

Community
  • 1
  • 1
Croc Studio
  • 141
  • 3