Javascript для группировки данных с помощью forloop

#javascript #arrays #loops #for-loop

#javascript #массивы #циклы #for-цикл

Вопрос:

Я получил данные ниже

 const v=[
    ...
    [2,'apple'],
    [3,'apple'],
    [4,'apple'],
    [5,'banana'],
    [6,'banana'],
    [7,'orange'],
    [8,'apple'],
    [9,'orange'],
    [10,'orange'],
    ...
]
  

Теперь я хочу разобрать его на

 {start:2 , end:4, value: 'apple'},
{start:5 , end:6, value: 'banana'},
{start:7 , end:7, value: 'orange'},
{start:8 , end:8, value: 'apple'},
{start:9 , end:10, value: 'orange'},
...
  

Итак, я делаю цикл следующим образом

 arr = []
v.forEach((j, i) => {
    if (!start amp;amp; !value) {
        let start = v[i][0]
        let value = v[i][1]
    }
    console.log(start,value)

    if (start amp;amp; value) {
        if (v[i   1] amp;amp; v[i   1][1] !== value) {
            let end = v[i][0]
            arr.push(
                {
                    start, end, value
                })
            delete start, end, value;
        }
    }
})

  

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

Есть ли другой способ сделать это?

Ответ №1:

Вы могли бы достичь того же с reduce , чтобы объединить элементы fruit и относительные числа,
а затем map результат:

 const v = [
  [2, 'apple'],
  [3, 'apple'],
  [4, 'apple'],
  [5, 'banana'],
  [6, 'banana'],
  [7, 'orange'],
  [8, 'apple'],
  [9, 'orange'],
  [10, 'orange'],
]

const reduced = v.reduce((ac, [num, fruit]) => ({
  ...ac,
  [fruit]: [...(ac[fruit] || []), Number(num)]
}), {})



const mapped = Object.entries(reduced).map(([fruit, v]) => ({
  value: fruit,
  end: Math.max(...v),
  start: Math.min(...v)
}))

console.log('mapped', mapped)  

Комментарии:

1. даже я думал о том же, но у меня есть сомнения, поскольку в случае, когда начало и конец перекрываются

2. Если мы напишем этот код в одну строку, убрав пробелы, это будет выглядеть как магическое заклинание: v.reduce((ac,[num,fruit])=>({...ac,[fruit]:[...(ac[fruit]||[]),Number(num)]}),{}) … Надеюсь, это не так сложно для начинающего тему = D

3. @maioman Спасибо за ваш ответ, но 8 — это яблоко, а 9,10 — снова оранжевый, это должно создать новый элемент… Извините за отсутствие вопросов…

4. @brk Потому что данные предназначены для зацикливания в шаблоне, и я обработал, если в нем start = end

Ответ №2:

Простой цикл, проверяющий с последним индексом, что это то же значение.

 const v=[
    [2,'apple'],
    [3,'apple'],
    [4,'apple'],
    [5,'banana'],
    [6,'banana'],
    [7,'orange'],
    [8,'apple'],
    [9,'orange'],
    [10,'orange'],
]

const result = []
for (var i=0; i< v.length; i  ) {
  var current = result[result.length-1];
  if (!current || current.value !== v[i][1]) {
    result.push({ start: v[i][0], end: v[i][0], value: v[i][1] });
  } else {
    current.end = v[i][0];
  }
}

console.log(result);  

Используя reduce

 const v=[
    [2,'apple'],
    [3,'apple'],
    [4,'apple'],
    [5,'banana'],
    [6,'banana'],
    [7,'orange'],
    [8,'apple'],
    [9,'orange'],
    [10,'orange'],
]

const result = v.reduce( (result, [index, value]) => {
  const current = result[result.length-1];
  if (!current || current.value !== value) {
    result.push({ start: index, end: index, value });
  } else {
    current.end = index;
  }
  return resu<
}, [])

console.log(result);