JS / TS, как перебрать массив объектов и изменить значения - PullRequest
0 голосов
/ 18 октября 2018

рассмотрим следующий массив.

routingButtonsHighlighter = [
  {vehicle: true},
  {userAssignment: false},
  {relations: false}
];

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

1) будет устанавливать для всех членов значение false 2) устанавливать для выбранного элемента значение true (передается какпараметр)

Ответы [ 3 ]

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

Отсутствие более специфических требований - это приключение на выбор.

(Примечание. Для краткости в этом коде используются вычисленные имена свойств ES6 и , деструктурирующие присваивания и ES2018 синтаксис расширения объекта , каждый из которых может бытьпередается с помощью TypeScript.)

Если каждый объект имеет ровно одну клавишу

  • ... и вы хотите изменить исходный массив и объекты

const objects = [ { vehicle: true }, { userAssignment: false }, { relations: false } ];

function selectKey(objects, selectedKey) {
  for (let obj of objects) {
    const [key] = Object.keys(obj);
    obj[key] = key === selectedKey;
  }
  return objects;
}

selectKey(objects, 'userAssignment');
console.log(objects);
  • ... и вам нужен новый массив новых объектов

const objects = [ { vehicle: true }, { userAssignment: false }, { relations: false } ];

function selectKey(objects, selectedKey) {
  const newObjects = [];

  for (let obj of objects) {
    const [key] = Object.keys(obj);
    newObjects.push({ [key]: key === selectedKey });
  }
  
  return newObjects;
}

console.log(selectKey(objects, 'userAssignment'))
  • ... но вам действительно нравится функциональный стиль

const objects = [ { vehicle: true }, { userAssignment: false }, { relations: false } ];

function selectKey(objects, selectedKey) {
  return objects.map(obj => {
    const [key] = Object.keys(obj);
    return { [key]: key === selectedKey };
  });
}

console.log(selectKey(objects, 'userAssignment'))

Если объекты могут иметь более одного ключа

  • ... и вы хотите изменить исходный массив и объекты

const objects = [
  { vehicle: true, relations: false },
  { userAssignment: false, vehicle: true },
  { relations: false, userAssignment: false },
];

function selectKey(objects, selectedKey) {
  for (let obj of objects) {
    for (let key of Object.keys(obj)) {
      obj[key] = key === selectedKey;
    }
  }
  return objects;
}

selectKey(objects, 'userAssignment');
console.log(objects);
  • ... и вам нужен новый массив новых объектов

const objects = [
  { vehicle: true, relations: false },
  { userAssignment: false, vehicle: true },
  { relations: false, userAssignment: false },
];

function selectKey(objects, selectedKey) {
  const newObjects = [];

  for (let obj of objects) {
    const newObj = {};
    for (let key of Object.keys(obj)) {
      newObj[key] = key === selectedKey;
    }
    newObjects.push(newObj);
  }
  
  return newObjects;
}

console.log(selectKey(objects, 'userAssignment'))
  • ... но вам действительно нравится функциональный стиль

const objects = [
  { vehicle: true, relations: false },
  { userAssignment: false, vehicle: true },
  { relations: false, userAssignment: false },
];

function selectKey(objects, selectedKey) {
  return objects.map(obj =>
    Object.keys(obj).reduce((newObj, key) =>
      ({ ...newObj, [key]: key === selectedKey }),
      {}
    )
  );
}

console.log(selectKey(objects, 'userAssignment'))
0 голосов
/ 18 октября 2018

Создание метода для чего-то подобного было бы узкоспециализированным, поэтому, чтобы абстрагировать его, я решил написать его так:

function arrayFlagSinglePropertyTrue(key, arrayofobjects) {

    for (let i in arrayofobjects) {

        let keys = Object.keys(arrayofobjects[i]);
        if (keys[0] == key) {
            arrayofobjects[i][keys[0]] = true;
        } else {
            arrayofobjects[i][keys[0]] = false;
        }

    }

    return arrayofobjects;

}

routingButtonsHighlighter = [
    {vehicle: true},
    {userAssignment: false},
    {relations: false}
];

console.log(arrayFlagSinglePropertyTrue("relations", routingButtonsHighlighter));

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


Редактировать: Несколько советов:

Единообразие в списках помогает избежать возникшей проблемы.Структурируя ваши объекты с единообразными именами свойств, а затем воздействуя на сами значения, вам больше не требуется использование специализированных функций или кода для его изменения.На этом этапе вы можете положиться на фундаментальную логику программирования для эффективного изменения свойств.

Если вы получаете список из какого-либо внешнего источника и не можете его контролировать, то вам, возможно, придется либо реорганизовать его самостоятельно.Если вы не можете сделать специализированные функции / коды, это ваше последнее средство.

Если возможно, возьмите что-то вроде этого:

routingButtonsHighlighter = [
    {vehicle: true},
    {userAssignment: false},
    {relations: false}
];

Организовать его в нечто вроде этого, где реальные свойства объектаодинаковы:

let betterStructureObject = [
    { propertyName: "vehicle", status: true },
    { propertyName: "userAssignment", status: false },
    { propertyName: "vehicle", status: false },
]

Так что вы можете легко зацикливаться на нем и не беспокоиться о написании специализированного кода.

for (let i in betterStructureObject) {

    if (betterStructureObject[i].propertyName == "vehicle")
         betterStructureObject[i].status = true;

    else betterStructureObject[i].status = false;

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

Вы можете перебрать массив с помощью Array.forEach(), получить ключ с помощью Object.keys(), сравнить с выбранным ключом и установить соответствующее значение:

const routingButtonsHighlighter = [{vehicle: true}, {userAssignment: false}, {relations: false}];

const select = (arr, selectedKey) =>
  arr.forEach((o) => {
    const key = Object.keys(o)[0];
    
    o[key] = key === selectedKey;
  });
  
select(routingButtonsHighlighter, 'userAssignment');

console.log(routingButtonsHighlighter);
...