-1

I am using Vue.js

What I want is to get one column named 'name' from the multidimensional array.

I am not sure the dimensional size of this multidimensional array.

Sample array is here

{
    "form":{
        "id":"123465",
        "title":"User Information",
        "fields":[
                    {
                        "type":"date",
                        "title":"Document date",
                        "name":"document_date",
                        "required":true
                    },
                    {
                        "type":"input",
                        "title":"Document no",
                        "name":"document_no",
                        "required":true
                    }
                ],
        "tabs":{
            "xxx-general":{
                "title":"General",
                "fields":[
                    {
                        "type":"date",
                        "title":"DOB",
                        "name":"dob"
                    },
                    {
                        "type":"toggle",
                        "title":"Keep my profile private",
                        "name":"is_private"
                    },
                ]
            },
            "xxx-times":{
                "title":"Ticket",
                "fields":[
                    {
                        "type":"datetime",
                        "title":"Arrival time",
                        "name":"arrival_time"
                    },
                    [
                        {"type":"number","title":"Quantity","name":"quantity"},
                        {"type":"currency","title":"Price","name":"price"}
                    ]
                ]
            }
        }
    }
}

I know there is array_column function in PHP, I want to use the javascript function equivalent to this PHP function.

Anyone helps me

Igor Carvalho
  • 668
  • 5
  • 19
  • What is your desired output? – CertainPerformance Jan 09 '19 at 09:57
  • `form['fields'][0]['name']` does not work? – AntonyMN Jan 09 '19 at 09:59
  • There's no such native function in JS, you've to iterate through the object and create an array of the desired values. – Teemu Jan 09 '19 at 10:00
  • 3
    @AntonyMN it's not dynamic - `array_column` invocation would look like `array_column(input, "name")` and would pull out that data from any amount of nesting in the object. But as Teemu says, there is no built in functionality in JS for that. You have to either roll your custom one or use a library. – VLAZ Jan 09 '19 at 10:02
  • 1
    The base to build on your own attempt for the task, you can find at https://stackoverflow.com/q/11922383/1169519 – Teemu Jan 09 '19 at 10:07

3 Answers3

1

As others already said, there is no native solution (as a function) in JavaScript. Instead, you have to use multiple steps. You might want to create some general purpose functions which you can use later on.

Hint: I shortended your example data for better readability!

var DATA = {
    "form":{
        "id":"123465",
        "title":"User Information",
        "fields":[
                    {
                        "type":"date",
                        "title":"Document date",
                        "name":"document_date",
                        "required":true
                    },
                    {
                        "type":"input",
                        "title":"Document no",
                        "name":"document_no",
                        "required":true
                    }
                ],
        "tabs":{
            // ... shortened ...
        }
    }
}



// ====== GENERAL PURPOSE FUNCTIONS ======
function prop (path, obj) {
  return path.split('.').reduce(function (p, name) {
    return p == null ? p : p[name];
  }, obj);
}

function mapMaybe (func, arr) {
  return Array.isArray(arr) ? arr.map(func) : [];
}

function mapDeep (path, func, obj) {
  return mapMaybe(func, prop(path, obj));
}



// ====== SOLUTION ======
console.log(mapDeep('form.fields', function (x) { return x.name; }, DATA))
David
  • 3,552
  • 1
  • 13
  • 24
0

there is no a native method to do perform a deep find but implementation is actually pretty easy:

//return an array of objects according to key, value, or key and value matching
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(obj);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(obj);
            }
        }
    }
    return objects;
}

//return an array of values that match on a certain key
function getValues(obj, key) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getValues(obj[i], key));
        } else if (i == key) {
            objects.push(obj[i]);
        }
    }
    return objects;
}

//return an array of keys that match on a certain value
function getKeys(obj, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getKeys(obj[i], val));
        } else if (obj[i] == val) {
            objects.push(i);
        }
    }
    return objects;
}


var json = '{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","ID":"44","str":"SGML","GlossSeeAlso":["GML","XML"]},"GlossSee":"markup"}}}}}';

var js = JSON.parse(json);

//example of grabbing objects that match some key and value in JSON
console.log(getObjects(js,'ID','SGML'));
//returns 1 object where a key names ID has the value SGML

//example of grabbing objects that match some key in JSON
console.log(getObjects(js,'ID',''));
//returns 2 objects since keys with name ID are found in 2 objects

//example of grabbing obejcts that match some value in JSON
console.log(getObjects(js,'','SGML'));
//returns 2 object since 2 obects have keys with the value SGML

//example of grabbing objects that match some key in JSON
console.log(getObjects(js,'ID',''));
//returns 2 objects since keys with name ID are found in 2 objects

//example of grabbing values from any key passed in JSON
console.log(getValues(js,'ID'));
//returns array ["SGML", "44"] 

//example of grabbing keys by searching via values in JSON
console.log(getKeys(js,'SGML'));
//returns array ["ID", "SortAs", "Acronym", "str"] 

Ref: http://techslides.com/how-to-parse-and-search-json-in-javascript

Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
0

Just to add one more solution to previous answers:

const data = {
  "form":{
    "id":"123465",
    "title":"User Information",
    "fields":[
      {
        "type":"date",
        "title":"Document date",
        "name":"document_date",
        "required":true
      },
      {
        "type":"input",
        "title":"Document no",
        "name":"document_no",
        "required":true
      }
    ],
    "tabs":{
      "xxx-general":{
        "title":"General",
        "fields":[
          {
            "type":"date",
            "title":"DOB",
            "name":"dob"
          },
          {
            "type":"toggle",
            "title":"Keep my profile private",
            "name":"is_private"
          },
        ]
      },
      "xxx-times":{
        "title":"Ticket",
        "fields":[
          {
            "type":"datetime",
            "title":"Arrival time",
            "name":"arrival_time"
          },
          [
            {"type":"number","title":"Quantity","name":"quantity"},
            {"type":"currency","title":"Price","name":"price"}
          ]
        ]
      }
    }
  }
};

const re = /"name"\s*:\s*"(.+?)(?<!\\)"/g;
const names = [];
const json = JSON.stringify(data);
let p;
while ((p = re.exec(json)) !== null) {
  names.push(p[1]);
}

console.log(names);
Styx
  • 9,863
  • 8
  • 43
  • 53