сопоставить массив 2 объекта и заполнить логический массив - PullRequest
1 голос
/ 01 апреля 2020

У меня есть этот первый массив, в конце каждого элемента он имеет числовое значение.

const arr = ["abc#1","def#2","z#1", "z#2"]

Мне нужно сопоставить его с массивом ниже

const arrObj = [{
  name: 'abc'
},{
  name: 'def'
},{
  name: 'z'
}]

, чтобы заполнить новый значение свойства, которое имеет логическое значение в массиве

result = [{
  name: 'abc',
  value: [true, false]
},{
  name: 'def',
  value: [false, true]
},{
  name: 'z',
  value: [true, true]
}]

Я застрял при выполнении нескольких итераций, но не смог получить вышеуказанный результат.

const arr = ["abc#1","def#2","z#1", "z#2"]

let arrObj = [{
  name: 'abc'
},{
  name: 'def'
},{
      name: 'z'
    }]

const raw = arr.map(o => o.split('#')[0])
const key = arr.map(o => o.split('#')[1])

arrObj = arrObj.map(o => {

  console.log('raw', raw)

  if(raw.includes(o.name)) {
    console.log('key', key)
    console.log(o.name)
  }

  return {
    ...o,
    value: []
  }
})

Ответы [ 3 ]

1 голос
/ 01 апреля 2020

Добавьте следующее к каждому объекту массива объектов (objArray):

objArray.forEach(object => object.value = [false, false]);
// ex. value: [false, false]

Затем .split() каждая строка массива строк (strArray) в га sh #

let subArray = string.split('#');
// ex. ["abc", "1"]

Преобразование второй строки в вещественное число. Примечание: этот шаг не нужен, если строки были правильно пронумерованы - напр. const strArray = ["abc#0", "def#1", ...]

let index = Number(subArray[1]) - 1;

Выполните итерацию по objArray снова и установите каждый элемент в подмассиве value в true в соответствии с соответствием object.name и subArray[0] и соответствующим index число.

object.value[index] = true;

Демо

Подробности также прокомментированы в демоверсии

const strArray = ["abc#1", "def#2", "z#1", "z#2"];
let objArray = [{
  name: 'abc'
}, {
  name: 'def'
}, {
  name: 'z'
}];

/*
Assign each object in objArray defaults to:
value: [false, false]
*/
objArray.forEach(object => object.value = [false, false]);

// Uncomment line below to view in console 
/*
console.log(`~~~~~~~ objArray - initial state ~~~~~~~`);
console.log(JSON.stringify(objArray));
console.log(`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`);
console.log(`~~~~~~~ Sub-arrays from strArray ~~~~~~~`);
*/

for (let string of strArray) {
  /*
  Convert each string of strArray to a subArray:
  ex. ["abc", "1"]
  */
  let subArray = string.split('#');
  // Convert the second string into a real index number
  let index = Number(subArray[1]) - 1;

  for (let object of objArray) {
    /*
    if object name matches the first string of a subArray...
    Change the object value to true at the index previously defined
    */
    if (object.name === subArray[0]) {
      object.value[index] = true;
    }
  }
  // Uncomment line below to view in console 
  //console.log(JSON.stringify(`['${subArray[0]}', '${subArray[1]}'] --> object.value index: ${index}`));
}

console.log(`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`);
console.log(`~~~~~~~~ objArray - final state ~~~~~~~~`);
console.log(JSON.stringify(objArray));
console.log(`~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`);

for...of Петли

Примечание: это не имеет прямого отношения к ответу. Это ответ на комментарий ниже:

, но вы не можете иметь индекс в for...of - user3106579

См. этот пример раздела MDN для .entries() метода.

const paragraphs = [...document.querySelectorAll('p')];

for (let [index, paragraph] of paragraphs.entries()) {
  if (index % 2 !== 0) {
    paragraph.style.color = 'tomato';
  }
}

paragraphs.forEach((paragraph, index) => {
  if (index % 2 === 0) {
    paragraph.style.color = 'blue';
  }
});

for (let i = 0; i < paragraphs.length; i++) {
  if (i % 2 !== 0) {
    paragraphs[i].style.backgroundColor = '#000';
  }
}
*>* {
  margin-left: 15px
}

p {
  width: max-content;
  margin-left: 30px
}

main,
h1,
section,
h2,
article,
h3 {
  margin-top: -40px: margin-bottom: -40px;
}

.as-console-wrapper {
  width: 350px;
  min-height: 100%;
  margin-left: 45%;
}
<main>
  <h1>Main</h1>
  <section>
    <h2>Section A</h2>
    <p>Paragraph aa</p>
    <p>Paragraph ab</p>
    <article>
      <h3>Article A1</h3>
      <p>Paragraph A1a</p>
      <p>Paragraph A1b</p>
      <p>Paragraph A1c</p>
    </article>
    <p>Paragraph ac</p>
    <article>
      <h3>Article A2</h3>
      <p>Paragraph A2a</p>
      <p>Paragraph A2b</p>
    </article>
    <p>Paragraph ad</p>
  </section>
  <section>
    <h2>Section B</h2>
    <p>Paragraph ba</p>
    <article>
      <h3>Article B1</h3>
      <p>Paragraph B1a</p>
      <p>Paragraph B1b</p>
      <p>Paragraph B1c</p>
      <p>Paragraph B1d</p>
    </article>
    <p>Paragraph bb</p>
    <p>Paragraph bc</p>
  </section>
</main>
0 голосов
/ 01 апреля 2020

Попробуйте это ( ОБНОВЛЕНО ) решение:

const arr = ['abc#1', 'def#2', 'z#1', 'z#2', 'anotherName#4'];

const arrObj = [
  { name: 'abc' },
  { name: 'def' },
  { name: 'z' }, 
  { name: 'anotherName' }
];

// find min and max IDs
let minId;
let maxId;
arr.forEach(str => {
  const id = +str.split('#')[1];
  minId = typeof minId === 'undefined' || id < minId ? id : minId;
  maxId = typeof maxId === 'undefined' || id > maxId ? id : maxId;
});

// build array of integers staring from minId to maxId including
const arrSize = maxId - minId + 1;
const booleanArr = Array.from(Array(arrSize)).map((_, i) => minId + i);

const arrMap = arr.reduce((res, curr) => ({
  ...res,
  [curr]: 1
}), {});

const result = arrObj.map(({name}) => ({
  name,
  value: booleanArr.map(i => Boolean(arrMap[`${name}#${i}`]))
}));

console.log(result);
0 голосов
/ 01 апреля 2020

Вы можете сделать это следующим образом:

const arr = ["abc#1","def#2","z#1", "z#2", "anotherName#4"]
      
const boolLength = arr.reduce((r, x) => {
  const [a, b] = x.split('#');
  return +b > r ? b : r
}, 0);

const tempObject = arr.reduce((r, x) => {

  const [a, b] = x.split('#');

  const array = r[a] || Array.from({length: boolLength}, (x, i) => false)
  array[b - 1] = true;

  return { 
   ...r,
   [a]: array
};

}, {});


const result = Object.keys(tempObject).reduce((r, x) => [
  ...r, 
  {
    name: x,
    value: tempObject[x]
  }
], []);
      
console.log(result);

Сначала сохраните в boolLength максимальную длину логического массива. Затем сохраните объект «n tempObject», чтобы предотвратить повторение свойств name. И наконец, в result составьте массив.

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