Построить объект из ключей в массиве - PullRequest
0 голосов
/ 16 октября 2018

Например, если у нас есть существующий объект

const mainObject = {
  title: 'some title',
  topics: {
    topic1: {
      path: '',
      id: 1
    },
    topic2: {
      path: '',
      id: 2
    }
  }
}

, и у меня есть функция, которая получает массив, содержащий ключи, например,

const arrayOfKeys = ['topics', 'topic1'];

function getObjectByKeys(arrayOfKeys) {
  // problem is length of the array may change
  const myObject = mainObject[arrayOfKeys[0]][arrayOfKeys[1]];
  return myObject;
}

функция должна вернуть

{
      path: '',
      id: 1
}

Ответы [ 6 ]

0 голосов
/ 16 октября 2018

Я бы поменял темы в массив, поэтому поиск любого элемента становится тривиальным.Теперь этот код почти удобен для чтения человеком: «найдите запись с идентификатором 1 внутри field_name основного объекта.»

const mainObject = {
  title: 'some title',
  topics: [
    { id: 1, path: 'first' },
    { id: 2, path: 'second' }
  ]
};
const field_name = 'topics';
const entry_to_find = 1;

const entry = mainObject[ field_name ].find( entry => entry.id === entry_to_find );
console.log( entry );
0 голосов
/ 16 октября 2018

Вы можете редактировать свою функцию, как показано ниже, и она даст вам желаемый результат.

function getObjectByKeys(obj, [first, ...rest]) {
  if(rest.length > 0 ) return getObjectByKeys(obj[first], rest) 
  else return obj[first]
}

getObjectByKeys(mainObject, ['topics', 'topic1'])
0 голосов
/ 16 октября 2018

вы можете использовать рекурсив.

const mainObject = {
  title: 'some title',
  topics: {
    topic1: {
      path: '',
      id: 1
    },
    topic2: {
      path: '',
      id: 2
    },
    topic3: {
      path: 'more depth',
      subtopic: {
        path: '',
        id: 4
      },
      id: 3
    }
  }
}

const arrayOfKeys = ['topics', 'topic3', 'subtopic'];

function getObjectByKeys(arrayOfKeys, currentObj, index = 0) {
  if(index >= arrayOfKeys.length) {
    return currentObj;
  }
  return getObjectByKeys(arrayOfKeys, currentObj[arrayOfKeys[index]], index+1)
}

console.log(getObjectByKeys(arrayOfKeys, mainObject));
0 голосов
/ 16 октября 2018

Вы можете использовать уменьшить ()

const mainObject = {
  title: 'some title',
  topics: {
    topic1: {
      path: '',
      id: 1
    },
    topic2: {
      path: '',
      id: 2
    }
  }
};
const arrayOfKeys = ['topics', 'topic1'];

var aa= arrayOfKeys.reduce((carry,value,index)=>{
             return carry[value];
        },mainObject);
        
console.log(aa);
0 голосов
/ 16 октября 2018

Одним из возможных решений может быть использование цикла forEach.

const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 } } }
const arrayOfKeys = ['topics', 'topic1'];

function getObjectByKeys(arrayOfKeys) {
  let result = Object.assign({}, mainObject);
  arrayOfKeys.forEach(function(key){
    result = result[key];
  });
  return result;
}

console.log(getObjectByKeys(arrayOfKeys));

Другой подход заключается в использовании метода reduce путем передачи функции callback в качестве аргумента.

const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 } } }
const arrayOfKeys = ['topics', 'topic1'];

getObjectByKeys = (arrayOfKeys) => {
  return arrayOfKeys.reduce((obj, item) => obj[item], mainObject);
}

console.log(getObjectByKeys(arrayOfKeys));
0 голосов
/ 16 октября 2018

Вы можете использовать .reduce здесь.Инициализируйте аккумулятор основным объектом и на каждой итерации его обратного вызова возвращайте значение, соответствующее текущему ключу.

const mainObject = {
  title: 'some title',
  topics: {
    topic1: {
      path: '',
      id: 1
    },
    topic2: {
      path: '',
      id: 2
    }
  }
}

const arrayOfKeys = ['topics', 'topic1'];

function getObjectByKeys(arrayOfKeys) {
  return arrayOfKeys.reduce((a, el, i, arr) => {
    return a[el] || {};    
  }, mainObject);
}

console.log(getObjectByKeys(arrayOfKeys));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...