0

I am trying to grab properties from an array of objects based on a matching title passed to an API call. I have the following two objects:

The first object is a simple title:

{
    "title": "Demo Import - Successful"
}

The second object is an array containing the above field and additional information:

"data": [{
        "columns": [
            "_source"
        ],
        "sort": [
            "example-timestamp",
            "asc"
        ],
        "title": "Demo Import - Authorization Failure"
    },
    {
        "columns": [
            "m-Form",
            "_type",
            "m-Identity"
        ],
        "sort": [
            "_type",
            "asc"
        ],
        "title": "Demo Import - Timed Out"
    },
    {
        "columns": [
            "_source"
        ],
        "sort": [
            "example-timestamp",
            "asc"
        ],
        "title": "Demo Import - Successful"
    }
]

I am currently trying to figure out how to find the matching property between the two objects, and then grab the rest of the information associated to that title in the following from:

{
    "title": "Demo Import - Successful",
    "sort": "example-timestamp",
    "direction": "asc",
    "columns": [_source]
}

Could someone provide me with a bit of guidance? I am still pretty new to working with objects in JavaScript. My current idea is to loop through data, and check each index for a matching title property. If there is a match, store the columns and title property, and then manipulate the sort properties into the form of

{
    "title": data.index.title,
    "sort": data.index.sort[0],
    "direction": data.index.sort[1],
    "columns": data.index.columns
}

Here is my current attempt that I can't quite get to work:

var match_title = {
    "title": "Demo Import - Successful"
};

var objects =
    "data": [{
            "columns": [
                "_source"
            ],
            "sort": [
                "example-timestamp",
                "asc"
            ],
            "title": "Demo Import - Authorization Failure"
        },
        {
            "columns": [
                "m-Form",
                "_type",
                "m-Identity"
            ],
            "sort": [
                "_type",
                "asc"
            ],
            "title": "Demo Import - Timed Out"
        },
        {
            "columns": [
                "_source"
            ],
            "sort": [
                "example-timestamp",
                "asc"
            ],
            "title": "Demo Import - Successful"
        }
    ];

function getObjects(name, data) {
    for (var i = 0, i < data.length, i++) {
        if (name.title == data[i].title) {
            var response = {
                "title": data[i].title,
                "sort": data[i].sort[0],
                "direction": data[i].sort[1],
                "columns": data[i].columns
            }
            return response;
        };
    };
};

var matchedObject = getObjects(match_title, objects);

Thank you in advance for you help.

EDIT: Solved. Thank you everyone for the quick answers and great explanations!

10
  • 2
    Possible duplicate of How to filter JSON Data in JavaScript or jQuery? Commented Jul 17, 2017 at 15:15
  • 1
    So, you want a new property called direction to be created with a value that is equal to the second item in the sort array property? Commented Jul 17, 2017 at 15:15
  • Simplest solution is a for-loop. Commented Jul 17, 2017 at 15:20
  • getObjects(match_title, objects.data); Commented Jul 17, 2017 at 15:25
  • @ScottMarucs yeah. I'm trying to programatically match elasticsearch saved search objects to their actual query, and the elasticsearch query takes a direction and a sort parameter, where the the saved search objects combine the two into a single sort object. Got it now! Commented Jul 17, 2017 at 15:31

3 Answers 3

1

You could try a combination of Array#filter and Array#map

var match_title = {
  "title": "Demo Import - Successful"
};

var objects = {
  "data": [{
      "columns": [
        "_source"
      ],
      "sort": [
        "example-timestamp",
        "asc"
      ],
      "title": "Demo Import - Authorization Failure"
    },
    {
      "columns": [
        "m-Form",
        "_type",
        "m-Identity"
      ],
      "sort": [
        "_type",
        "asc"
      ],
      "title": "Demo Import - Timed Out"
    },
    {
      "columns": [
        "_source"
      ],
      "sort": [
        "example-timestamp",
        "asc"
      ],
      "title": "Demo Import - Successful"
    }
  ]
};

function getObjects(name, data) {
  return data.filter(function(d) {
    return name.title == d.title;
  }).map(function(d) {
    return {
      "title": d.title,
      "sort": d.sort[0],
      "direction": d.sort[1],
      "columns": d.columns
    }
  });
};

var matchedObject = getObjects(match_title, objects.data);
console.log(matchedObject)

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

2 Comments

If I use this method, how do I access the properties of matchedObject? I am trying to call matchedObject.title, but it comes back undefined.
This returns an array. So if you had multiple matching objects, you'll get all of them. So, for your particular example, you can use matchedObject[0]
1

your objects is not valid, then a lot error in your code, here the fix

var match_title = {
  "title": "Demo Import - Successful"
};

var objects = {
  "data": [{
      "columns": [
        "_source"
      ],
      "sort": [
        "example-timestamp",
        "asc"
      ],
      "title": "Demo Import - Authorization Failure"
    },
    {
      "columns": [
        "m-Form",
        "_type",
        "m-Identity"
      ],
      "sort": [
        "_type",
        "asc"
      ],
      "title": "Demo Import - Timed Out"
    },
    {
      "columns": [
        "_source"
      ],
      "sort": [
        "example-timestamp",
        "asc"
      ],
      "title": "Demo Import - Successful"
    }
  ]
};

function getObjects(name, data) {
  for(var i = 0; i < data.data.length; i++) {
    if(name.title == data.data[i].title) {
      var response = {
        "title": data.data[i].title,
        "sort": data.data[i].sort[0],
        "direction": data.data[i].sort[1],
        "columns": data.data[i].columns
      };
      return response;
    }
  }
}

var matchedObject = getObjects(match_title, objects);
console.log(matchedObject);

2 Comments

Okay, so that's how you check the index of a nested object. using data.data[i] instead of data[i]. Good to know. Thanks for your help! Have a great day.
in function scope data is alias for objects, calling data.data same as objects.data
1

First, your objects JSON is invalid because you are trying to set objects to a property that stores an array, but you didn't wrap the object with { and }. You could just set the variable to a JSON array and then you don't need the property at all (and that's what I'm showing in my answer below).

The Array.filter() method can do this for you without explicit loops.

See below for corrections.

var match_title = { title: "Demo Import - Successful" };

var data = `[
    {
        "columns": [ "_source" ], 
        "sort": [ "example-timestamp", "asc" ],
        "title": "Demo Import - Authorization Failure"
    },
    {
        "columns": [ "m-Form", "_type", "m-Identity" ],
        "sort": [ "_type", "asc" ],
        "title": "Demo Import - Timed Out"
    },
    {
        "columns": [ "_source" ],
        "sort": [ "example-timestamp", "asc" ],
        "title": "Demo Import - Successful"
    }
]`;

// New object will be stored here
var result = null;

function getObjects(name, data) {

  // parse the JSON into an array and filter the array based on input
  var match = JSON.parse(data).filter(function (entry) {

   // Just check if the item being enumerated has the value you seek
   if (entry.title === name){ 
      // Add the new property and set the placeholder object to the result
      entry.direction = entry.sort[1];
      entry.sort.pop();  // Remove sort direction from property array
      result = entry;
   }
  });
};

// Invoke the function
getObjects(match_title.title, data);

// Get the entire matched object:
console.log(result);

// Or, just individual properties of it:
console.log(result.columns);
console.log(result.sort);
console.log(result.title);
console.log(result.direction);

7 Comments

What is the purpose of filter in this code? It's just doing the work that forEach would do.
That is a lot simpler, but how can we use that same technique while manipulating the "sort" field to only contain the value "example-timestamp" instead of the array containing the direction, too? Or should I just keep it as is, and when I want to use the sort field for my actual query, just call sort[0]?
@MaazSyedAdeeb Yes, but forEach() is a somewhat generic looping method. There are several others that are more specific (map, some, reduce, filter, every, etc.). forEach could be used instead of any of these, but the more specific ones tend to make the logic simpler in many cases or provided better semantics.
@JoeyMarinello Updated answer to do just that with Array.pop(), which removes the last element in an array.
Awesome, thank you! So if I want to now access those properties to use elsewhere, do I call "matchedObejct.title, matchedObject.columns, etc"?
|

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.