在同一属性上分组值

时间:2015-12-23 09:32:55

标签: javascript

我有一个这样的数组:

.main-content .popular {
  background: #fff;
}
.main-content .popular .item {
  float: left;
  width: 25%;
  text-align: center;
  position: relative;
  padding-bottom: 20px;
}
.main-content .popular .item:after {
  content: "";
  width: 2px;
  height: 100%;
  background: #f5f5f5;
  position: absolute;
  right: 0;
  top: 0;
}
.main-content .popular .item p {
  text-align: left;
  padding-left: 20px;
}
.main-content .popular .item p a {
  font-size: 16px;
  color: #414a56;
}

我想要的是将jsons与相同的单位值混合,加入品牌逗号分隔,以便结果数组为:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/bxslider/4.2.5/jquery.bxslider.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/bxslider/4.2.5/jquery.bxslider.min.js"></script>
<div class="main-content">

  <div class="popular">
    <div class="item">
      <img src="https://placeimg.com/200/150/nature">
      <br>
      <p>
        <a href="#">Item text 1</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/arch">
      <br>
      <p>
        <a href="#">Item text 2</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/nature">
      <br>
      <p>
        <a href="#">Item text 3</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/arch">
      <br>
      <p>
        <a href="#">Item text 4</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/nature">
      <br>
      <p>
        <a href="#">Item text 5</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/arch">
      <br>
      <p>
        <a href="#">Item text 6</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/nature">
      <br>
      <p>
        <a href="#">Item text 7</a>
      </p>
    </div>
    <div class="item">
      <img src="https://placeimg.com/200/150/arch">
      <br>
      <p>
        <a href="#">Item text 8</a>
      </p>
    </div>
    <div class="clear"></div>
  </div>

</div>

有人建议我使用[ {unit: 35, brand: 'CENTURY'}, {unit: 35, brand: 'BADGER'}, {unit: 25, brand: 'CENTURY'}, {unit: 15, brand: 'CENTURY'}, {unit: 25, brand: 'XEGAR'} ] ,我正在MDN上阅读它,而我不明白的是我怎么能使用最后一个被调用的参数:

  

使用三个参数调用回调:

     
      
  1. 元素的值
  2.   
  3. 元素的索引
  4.   
  5. 正在遍历的Array对象
  6.   

我的意思是,我知道它是完整的阵列,但如果我已经过滤了它,那对我有什么帮助呢?

[
    {unit: 35, brand: 'CENTURY, BADGER'},
    {unit: 25, brand: 'CENTURY, XEGAR'},
    {unit: 15, brand: 'CENTURY'}
]

5 个答案:

答案 0 :(得分:1)

OP使用filter要求解决方案。这是一个,但不比其他人好

var arr = [{
  unit: 35,
  brand: 'CENTURY'
}, {
  unit: 35,
  brand: 'BADGER'
}, {
  unit: 25,
  brand: 'CENTURY'
}, {
  unit: 15,
  brand: 'CENTURY'
}, {
  unit: 25,
  brand: 'XEGAR'
}]
var done = [];

var arr2 = arr.map(function(obj) {
  if (done.indexOf(obj.unit)>=0) return;
  done.push(obj.unit);
  var arrIn = arr.filter(function(objIn) {
    return obj.unit == objIn.unit;
  });
  return {
    unit: arrIn[0].unit,
    brand: arrIn.map(function(obj2) {
      return obj2.brand;
    }).join(',')
  };
});

document.write(JSON.stringify(arr2))

答案 1 :(得分:0)

迭代元素并生成新数组

var arr = [{
    unit: 35,
    brand: 'CENTURY'
  }, {
    unit: 35,
    brand: 'BADGER'
  }, {
    unit: 25,
    brand: 'CENTURY'
  }, {
    unit: 15,
    brand: 'CENTURY'
  }, {
    unit: 25,
    brand: 'XEGAR'
  }],
  ind = [],
  res = [];

// iterate over the array using forEach or for loop
arr.forEach(function(v) {
  // checking unit value is in `ind` array  
  var eleIn = ind.indexOf(v.unit);
  if (eleIn === -1) {
    // pushing unit value to `ind` array
    ind.push(v.unit);
    // pushing array element to `res` array
    res.push(v);
  } else
    // else case updating brand value
    res[eleIn].brand += ', ' + v.brand;
})

document.write('<pre>' + JSON.stringify(res, null, 3) + '</pre>');

答案 2 :(得分:0)

试试这个

var objArray = [
    {unit: 35, brand: 'CENTURY'},
    {unit: 35, brand: 'BADGER'},
    {unit: 25, brand: 'CENTURY'},
    {unit: 15, brand: 'CENTURY'},
    {unit: 25, brand: 'XEGAR'}
];

    var output = {};
    var outputArr = [];
    for( var counter = 0; counter < objArray.length; counter++ )
    {
       var unit = objArray[ counter ].unit;
       if ( !output [ unit ] )
       {
          output [ unit ] = [];
       }
       output [ unit ].push( objArray[ counter ].brand );
    }
     for ( var unit in output )
    {
      outputArr.push( { unit: unit, brand: output[ unit ].join( "," ) } );
    }
   console.log( outputArr );

答案 3 :(得分:0)

我在this fiddle找到了一个通用的解决方案。

field分组数据需要做什么。当找到匹配项时,它会修改具有该field的第一个对象,并将与该field匹配的其他实例上的所有属性添加到其中。 IE:如果您要在下面的unit 35实例上添加额外字段,则会将它们复制到组合实例中。可以通过注释掉最内层的else语句来关闭它。

这是代码

var data = [
    {unit: 35, brand: 'CENTURY'},
    {unit: 35, brand: 'BADGER'},
    {unit: 25, brand: 'CENTURY'},
    {unit: 15, brand: 'CENTURY'},
    {unit: 25, brand: 'XEGAR'}
];

function groupBy(field, data) {
  var result = [];
  var ignore = [];

  for (var i = 0; i < data.length; i++) {
    var current = data[i];
    var isNew = true;

    // Find matching elements
    for (var j = 0; j < data.length; j++) {
      var test = data[j];

      if (test != current && result.indexOf(test) == -1 && ignore.indexOf(test) == -1) {
        // If their fields match
        if (test[field] == current[field]) {
          for (var key in test) {
            if (test.hasOwnProperty(key) && key != field) {
              if (current.hasOwnProperty(key)) {
                var currentValues = current[key].split(", ");
                currentValues.push(test[key]);
                current[key] = currentValues.join(", ");
              } else {
                current[key] = test[key];
              }
            }
          }

          // Add to ignore list
          ignore.push(test);
        }
      }
    }

    if (ignore.indexOf(current) == -1) {
      result.push(current);
    }
  }
  return result;
}

var newData = groupBy('unit', data);
console.log(JSON.stringify(newData));

输出:

[
    {"unit":35,"brand":"CENTURY, BADGER"},
    {"unit":25,"brand":"CENTURY, XEGAR"},
    {"unit":15,"brand":"CENTURY"}
]

答案 4 :(得分:0)

这是一个使用Array.prototype.filter()和临时对象的非破坏性解决方案。

var array = [{ unit: 35, brand: 'CENTURY' }, { unit: 35, brand: 'BADGER' }, { unit: 25, brand: 'CENTURY' }, { unit: 15, brand: 'CENTURY' }, { unit: 25, brand: 'XEGAR' }];

function filter(a) {
    var o = {};
    return JSON.parse(JSON.stringify(a)).filter(function (b) {
        if (!(b.unit in o)) {
            o[b.unit] = b;
            return true;
        }
        o[b.unit].brand += ', ' + b.brand;
    });
}

document.write('<pre>' + JSON.stringify(filter(array), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');