使用lodash变换时如何包括删除的数组项

时间:2018-11-09 16:56:52

标签: javascript lodash

我正在使用lodash变换通过比较两个对象来生成更改消息。我需要检测某个项目是否已从数组中删除,并将该项目包括在更改消息中。如何将删除的项目推回到更改后的数组上?

var lhs = {
  "Income": [{
      "Id": 1,
      "MonthlyIncome": 5000,
      "Type": "Base"
    },
    {
      "Id": 2,
      "MonthlyIncome": 1000,
      "Type": "Overtime"
    }
  ]
};
var rhs = {
  "Income": [{
      "Id": 1,
      "MonthlyIncome": 5000,
      "Type": "Base"
    },
    {
      "Id": 0,
      "MonthlyIncome": 500,
      "Type": "Other"
    }
  ]
};

function difference(base, object) {
  function changes(object, base) {
    return _.transform(object, function(result, value, key) {
      if (!_.isEqual(value, base[key]) || key === 'Id') {
        if (!_.isEqual(value, base[key]) && key === "Id") {

          //The item at this position has been removed,
          //but needs to be include in the change message  
          //How to push this item onto the array ?
          var removedItem = {
            Id: base[key],
            Action: "remove"
          }
        }
        result[key] =
          _.isObject(value) && _.isObject(base[key]) ?
          changes(value, base[key]) :
          value;
      }
    });
  }
  return changes(object, base);
}

var changeMessage = JSON.stringify(difference(lhs, rhs));

console.log(changeMessage);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

changeMes​​sage的预期结果

{
    "Income": [
        {
            "Id": 0,
            "MonthlyIncome": 500,
            "Type": "Other"
        },
        {
            "Id": 2,
            "Action": "remove"
        }
    ]
}

2 个答案:

答案 0 :(得分:0)

let store = UserStore.create({...}) export default class App extends Component { render() { return ( <Provider store={store}> <Router /> </Provider> ); } } 存放在removedItem中。

result
var lhs = {
  "Income": [{
      "Id": 1,
      "MonthlyIncome": 5000,
      "Type": "Base"
    },
    {
      "Id": 2,
      "MonthlyIncome": 1000,
      "Type": "Overtime"
    }
  ]
};
var rhs = {
  "Income": [{
      "Id": 1,
      "MonthlyIncome": 5000,
      "Type": "Base"
    },
    {
      "Id": 0,
      "MonthlyIncome": 500,
      "Type": "Other"
    }
  ]
};

function difference(base, object) {
  function changes(object, base) {
    return _.transform(object, function(result, value, key) {
      if (!_.isEqual(value, base[key]) || key === 'Id') {
        if (!_.isEqual(value, base[key]) && key === "Id") {

          // stash the removedItem to the result
          result.removedItem = {
            Id: base[key],
            Action: "remove"
          }
        }
        result[key] =
          _.isObject(value) && _.isObject(base[key]) ?
          changes(value, base[key]) :
          value;
      }
    });
  }
  return changes(object, base);
}

var changeMessage = JSON.stringify(difference(lhs, rhs));

console.log(changeMessage);

答案 1 :(得分:0)

您也可以通过lodash来实现相同的目的:

var ld = { "Income": [{ "Id": 1, "MonthlyIncome": 5000, "Type": "Base" }, { "Id": 2, "MonthlyIncome": 1000, "Type": "Overtime" } ] }; var rd = { "Income": [{ "Id": 1, "MonthlyIncome": 5000, "Type": "Base" }, { "Id": 0, "MonthlyIncome": 500, "Type": "Other" } ] };

const changes = (a,b) => 
  _.filter(_.values(b.Income), x => !_.includes(_.mapValues(a.Income, 'Id'),x.Id))

const compare = (l,r) => {
  var plus = changes(l,r)
  var minus = _.map(changes(r,l), ({Id}) => ({ Id, Action: "remove" }))
  return [...plus, ...minus]
}

console.log(compare(ld,rd))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

与ES6相同:

var ld = { "Income": [{ "Id": 1, "MonthlyIncome": 5000, "Type": "Base" }, { "Id": 2, "MonthlyIncome": 1000, "Type": "Overtime" } ] }; var rd = { "Income": [{ "Id": 1, "MonthlyIncome": 5000, "Type": "Base" }, { "Id": 0, "MonthlyIncome": 500, "Type": "Other" } ] };

const ids = d => d.map(x => x.Id)
const changes = (a,b) => 
    Object.values(b.Income).filter(x => !ids(a.Income).includes(x.Id))

const compare = (l,r) => {
  var plus = changes(l,r)
  var minus = changes(r,l).map(({Id}) => ({ Id, Action: "Removed" }))
  return [...plus, ...minus]
}

console.log(compare(ld,rd))