0

I have an issue with the arrays.

My requirement: I have an object say

data = {
192.168.2.1: ["alpha", "beta", "delta"],
192.168.2.2: ["alpha"],
192.168.2.3: ["delta"],
192.168.2.4: []
}

I want to merge all the values (arrays) into one array so that I can read it from UI.

Desired Output: [alpha, beta, delta]

Current implementation:

var allControllerList = [];
var uniqueControllerList = [];


   $.each(data, function(i, el){
       allControllerList = allControllerList.concat(el);
   });

   $.each(allControllerList, function(index, el) {
        if($.inArray(el, uniqueControllerList) === -1) uniqueControllerList.push(el);
   });

If i want to read it on UI, I need to do this again:

            <select id='ssid-list' multiple='multiple'>
              <% _.each(uniqueControllerList, function(ssid, index) { %>
                <option value='<%=controllerIp+ssid%>'>
                    <%=ssid%>
                </option>
              <% }); %>
            </select>

I am reading an array three times, I was looking for a more efficient implementation. (Underscore, jQuery or JS).

Thanks,

1
  • 1
    What are alpha, beta, delta? Objects or primitive types? Commented Nov 4, 2016 at 20:02

2 Answers 2

3

Using Underscore.js

You can use _.union

var data = {
  "192.168.2.1": ["alpha", "beta", "delta"],
  "192.168.2.2": ["alpha"],
  "192.168.2.3": ["delta"],
  "192.168.2.4": []
}

//exctract values from the object
var values = _.values(data);

//use .apply() to give _.union() an array of arrays
var joinedData = _.union.apply(null, values);

console.log(joinedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Using vanilla JavaScript

You can simply join everything and then filter for uniqueness. Cross-browser compatible for IE9 and above (so, no IE8).

var data = {
  "192.168.2.1": ["alpha", "beta", "delta"],
  "192.168.2.2": ["alpha"],
  "192.168.2.3": ["delta"],
  "192.168.2.4": []
}

var seenItems = {};

//Object.values() is not widely supported, otherwise it would have been better
//_.values() can be used instead but this solution is showcasing pure JS
var joinedData = Object.keys(data)
  .reduce(function(memo, key){
    //combine all arrays into one
    return memo.concat(data[key]);
  }, [])
  .filter(function(item) {
    //filter the array by keeping track of what you've seen or not.
    var result = !seenItems[item];

    seenItems[item] = true;
    
    return result;
  });

console.log(joinedData);

Using ES6

Not widely supported in browsers, especially if you want to support something older than current browsers. However, at some point, however, adding it here because of how easy it is.

const data = {
  "192.168.2.1": ["alpha", "beta", "delta"],
  "192.168.2.2": ["alpha"],
  "192.168.2.3": ["delta"],
  "192.168.2.4": []
}

// combine all arrays together
const dupedData = [].concat(...Object.values(data));

//use a Set to remove duplicates and turn it into an array
const deDupedData = Array.from(new Set(dupedData));

console.log(deDupedData);

Sign up to request clarification or add additional context in comments.

Comments

1

I believe something like this may help

let data = {
    '192.168.2.2': ['alpha'],
    '192.168.2.3': ['delta'],
    '192.168.2.4': ['beta'],
    '192.168.2.5': ['alpha']
}

let key = Object.keys(data)

const array = []
for (key in data) {
  if (data[key]) {
    array.push(data[key].toString())
  }
}

console.log(array)

Comments

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.