JS / Lodash - заменить значения в многомерном объекте - PullRequest
0 голосов
/ 04 июля 2018

Я ищу эффективный способ замены значений в многомерном объекте, используя Lodash или даже vanilla JS.

У меня есть массив с многомерными объектами неизвестной глубины, такими как (упрощенно)

objects = [{
    id: 1,
    view: {
        id: 7
    }
}, {
    id: 2,
    view: {
        id: 9
    },
    childs: [{
        id: 3,
        view: {
            id: 3
        }
    }]
}];

Теперь я хочу заменить значение представления каждого узла именованной ссылкой на импорт, хранящейся в отдельном объекте. Ссылки доступны через view.id как индекс этого объекта. Так что я пытаюсь достичь что-то вроде этого

views = {
    3: some,
    7: random,
    9: imports
};

objects = [{
    id: 1,
    view: views[7]
}, {
    ...
}];

Хорошо, я знаю, как перебирать многомерный объект, чтобы достичь этого вручную, но, поскольку я работаю с большими объектами, было бы неплохо, если бы был более чистый и более производительный способ с использованием Lodash.

У кого-нибудь есть гениальное решение?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Поскольку lodash - это всего лишь служебный слой, написанный на JS, вы вряд ли получите какой-либо прирост производительности по сравнению с vanilla JS при его использовании.

Функция, представленная ниже, является, вероятно, самым быстрым способом сделать то, что вы хотите: она изменяет предоставленные объекты вместо создания новых и не выполняет итерацию по каждому ключу.

function transform(arr) {
  arr.forEach(obj => {
    if (obj.hasOwnProperty('view')) obj.view = views[obj.view.id];
    if (obj.hasOwnProperty('childs')) transform(obj.childs);
  });
}
0 голосов
/ 16 декабря 2018

Вы можете использовать рекурсивный _.transform() вызов для повторения и обновления представлений объектов:

const fn = o => _.transform(o, (acc, v, k) => {
  // if key is view, and it and has an id value replace it with equivalent from views
  if(_.eq(k, 'view') && _.has(v, 'id')) acc[k] = _.get(views, v.id, v);
  
  // if it's an object transform it recursively
  else if (_.isObject(v)) acc[k] = fn(v);
  
  // assign primitives to accumulator
  else acc[k] = v;
});

const objects = [{"id":1,"view":{"id":7}},{"id":2,"view":{"id":9},"childs":[{"id":3,"view":{"id":3}}]}];

const views = {
    3: 'some',
    7: 'random',
    9: 'imports'
};

const result = fn(objects);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
...