简体   繁体   中英

Looping inside of array with objects to get one of it property

I need a help with JS array task.

I have an array that looks like that:

const array = [
 {name: 'Show_Everything__c', controllerName: null, value: true},
 {name: 'Vehicle_Type__c', controllerName: 'Show_Everything__c', value: "Car"},
 {name: 'Car__c', controllerName: 'Vehicle_Type__c', value: "BMW"},
 {name: 'Model__c', controllerName: 'Car__c', value: '330i'}
];

and I have a key that represent one of those objects name.

What I'm trying to achieve is:

if my key=Vehicle_Type__c , I want to check if Vehicle_Type__c exist somewhere inside an array of objects as a controllerValue , if it's exist, than add it to new array, and (based on this example) because Vehicle_Type__c exist on an object with name Car__c , now I want to check if Car__c exist somewhere as a controllerName .

So I want to have an array that contains const newArray = [Car__c, Model__c ]

I had something like that right now:

const dependentField = array.find(field => field.controllerName === key).name;
const dependentField_2 = array.find(field => field.controllerName === dependentField).name;
const dependentField_3 = array.find(field => field.controllerName === dependentField_2).name;

But I would like to have something generic, without logic duplication.

Any ideas or examples would be highly appreciated, thank you so much.

You could create a function to make that search and called it recursively.

Solution 1

Simple code, to understand the logic (this solution will modify an initial global variable)

// Your data
const array = [
 {name: 'Show_Everything__c', controllerName: null, value: true},
 {name: 'Vehicle_Type__c', controllerName: 'Show_Everything__c', value: "Car"},
 {name: 'Car__c', controllerName: 'Vehicle_Type__c', value: "BMW"},
 {name: 'Model__c', controllerName: 'Car__c', value: '330i'}
];

// The final array with all founded names
const newArray = [];

// Your recursive function
const findName = (value) => {
    array.forEach((item) => {
        if (item.controllerName === value) {
            // If the key exists, save in the array and make a new search with this key                
            newArray.push(item.name);
            findName(item.name);
        }
    })
}

// Starts the application by calling the fuction with the initial desired value
findName("Vehicle_Type__c");

// Check the results
console.log(newArray);

Solution 2

More complex approach to use immutability principle

// Your data
const array = [
 {name: 'Show_Everything__c', controllerName: null, value: true},
 {name: 'Vehicle_Type__c', controllerName: 'Show_Everything__c', value: "Car"},
 {name: 'Car__c', controllerName: 'Vehicle_Type__c', value: "BMW"},
 {name: 'Model__c', controllerName: 'Car__c', value: '330i'}
];


// Your filter function
const findName = (value) => {
  const filteredData = array.filter(item => item.controllerName === value);
  const filteredName = filteredData.map(item => item.name);
  return filteredName;
}

// Your recursive and immutable function
const findDependencies = (acc, keyValue) => {
    const results = findName(keyValue);
    if (results.length > 0) {
      return results.map((item) => {
        return findDependencies([...acc, ...results], item);
      }).flat();
    } else {
      return acc;
    }
}

// Starts the application by calling the fuction with the initial desired value
const newArray = findDependencies([], "Show_Everything__c");

// Check the results
console.log(newArray);

You can reduce the array into the ones that are in the params list spread into an array and recursively call it with the new names until there are no more.

 const array = [ {name: 'Show_Everything__c', controllerName: null, value: true}, {name: 'Vehicle_Type__c', controllerName: 'Show_Everything__c', value: "Car"}, {name: 'Car__c', controllerName: 'Vehicle_Type__c', value: "BMW"}, {name: 'Model__c', controllerName: 'Car__c', value: '330i'} ]; const controllerNames = (array, ...controllers) => { const names = array.reduce((names, item) => controllers.some(c => item.controllerName === c) ? [...names, item.name] : names, []); return names.length ? [...names, ...controllerNames(array, ...names)] : names; }; console.log(controllerNames(array, 'Vehicle_Type__c')); 

array is the first paramaters and the ... spread operator collects the rest of the paramaters into an array. Reduce looks if the current controllerName is in the controllers array and returns a new array with it's name or return the existing names. [] is the starting accumulator of an empty name array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM